home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / program / freeli20.zip / freelib3.asx < prev    next >
Text File  |  1996-07-01  |  99KB  |  3,545 lines

  1. ; Hi-Res Text Mode library.  This is a 90x34 enhanced text mode.
  2. ; It requires VGA capability; do not load this on a CGA or EGA!
  3.  
  4. ; T. C. Andersen's graphics code starts on line 2286.
  5.  
  6. ~~~C_TXMAIN
  7. Ideal
  8.  
  9. Include     "textmac.inc"           ;Include macros
  10.  
  11. Public      CurSeg, W_X1, W_Y1, W_X2, W_Y2, W_Rel, Attr
  12. Public      inittext, closetext, clrscr, setcolor, getcolor
  13.  
  14. Model Tiny
  15. P186
  16. CodeSeg
  17.  
  18. ;****************** Data Section
  19.  
  20. EGAPal      dw 8010h,0000h,0101h    ;EGA palette
  21.             dw 0202h,0303h,0404h
  22.             dw 0505h,0606h,0707h
  23.             dw 0808h,0909h,0A0Ah
  24.             dw 0B0Bh,0C0Ch,0D0Dh
  25.             dw 0E0Eh,0F2Fh
  26.  
  27. DACPal      db 0,0,0,0,37,0,0,63    ;DAC palette:  New color set
  28.             db 0,37,63,37,0,0,63    ;with much more variety than
  29.             db 37,0,37,63,0,63,46   ;the standard EGA color set.
  30.             db 46,46,27,27,27,63    ;Also allows XOR cursor 07h
  31.             db 0,0,63,37,0,63,63    ;with 67% minimum contrast
  32.             db 0,0,37,63,0,0,37     ;and 75% average contrast.
  33.             db 0,63,63,63,63,63
  34.  
  35. CurSeg      dw 0                    ;Current segment
  36.  
  37. W_X1        dw 0                    ;Window values
  38. W_Y1        dw 0
  39. W_X2        dw 0
  40. W_Y2        dw 0
  41. W_Rel       dw 0
  42.  
  43. Attr        dw 0                    ;Current attribute
  44.  
  45. ;****************** inittext() -- Init text system
  46. ;void inittext(void);
  47.  
  48. Proc        inittext
  49.  
  50.             pusha                   ;Save all registers
  51.             push es
  52.  
  53.             push 0A000h             ;ES = video memory
  54.             pop es
  55.  
  56.             mov ax,3                ;Set 80x25 text mode
  57.             int 10h
  58.  
  59.             mov ax,1114h            ;Load standard 8x16 font
  60.             xor bl,bl
  61.             int 10h
  62.  
  63.             call SetSize            ;Set resolution
  64.  
  65.             mov dx,03D4h            ;CRTC port
  66.             mov ax,4013h            ;Fake 128 chars
  67.             out dx,ax               ;for efficiency
  68.  
  69.             mov dx,03DAh            ;IS1 port
  70.             in al,dx                ;Reset AC
  71.             mov dx,03C0h            ;AC port
  72.             mov si,offset EGAPal    ;Send palette
  73.             mov cx,34               ;via REP OUTSB
  74.             rep outsb
  75.  
  76.             mov dx,03C8h            ;DACWA port
  77.             xor al,al               ;Set address 0
  78.             out dx,al
  79.             inc dx                  ;DACD port
  80.             mov si,offset DACPal    ;Send palette
  81.             mov cx,48               ;via REP OUTSB
  82.             rep outsb
  83.  
  84.             mov [W_X2],89           ;Set variables:
  85.             mov [W_Y2],33           ;W_X2, W_Y2...
  86.  
  87.             xor ax,ax
  88.             mov [W_X1],ax           ;W_X1...
  89.             mov [W_Y1],ax           ;W_Y1...
  90.             mov [W_Rel],ax          ;W_Rel...
  91.             mov [Attr],07h          ;Attr...
  92.             mov [CurSeg],es         ;CurSeg...
  93.  
  94.             xor di,di               ;Clear video memory
  95.             mov cx,8000h
  96.             mov ax,0720h
  97.             rep stosw
  98.  
  99. in_done:    pop es                  ;Restore registers
  100.             popa
  101.             ret                     ;Return
  102.  
  103. EndP        inittext
  104.  
  105. ;****************** closetext() -- Close text system
  106. ;void closetext(void);
  107.  
  108. Proc        closetext
  109.  
  110.             push ax                 ;Save AX
  111.             mov ax,3                ;Set text video mode
  112.             int 10h
  113.             pop ax                  ;Restore AX
  114.             ret                     ;Return
  115.  
  116. EndP        closetext
  117.  
  118. ;****************** clrscr() -- Clear entire screen
  119. ;void clrscr(void);
  120.  
  121. Proc        clrscr
  122.  
  123.             pusha                   ;Save registers
  124.             push es
  125.  
  126.             mov es,[CurSeg]         ;ES = video memory
  127.  
  128.             xor di,di               ;Clear video page
  129.             mov cx,1000h
  130.             mov ax,0720h
  131.             rep stosw
  132.  
  133.             pop es                  ;Restore registers
  134.             popa
  135.             ret                     ;Return
  136.  
  137. EndP        clrscr
  138.  
  139. ;****************** SetSize -- Set 90x34 resolution
  140.  
  141. Proc        SetSize
  142.  
  143.             pusha                   ;Save all registers
  144.             mov dx,03C4h            ;Sequencer Port
  145.             mov ax,0100h            ;Synchronous reset
  146.             out dx,ax               ;Send command
  147.             inc ax                  ;8 pixels/char
  148.             out dx,ax               ;Send command
  149.  
  150.             mov dx,03CCh            ;Misc Output Read Port
  151.             in al,dx                ;Read value
  152.             and al,0F3h             ;Bits 2-3: 01 = 28MHz
  153.             or al,0C4h              ;Bits 6-7: 11 = 480 scanlines
  154.             mov dx,03C2h            ;Misc Output Write Port
  155.             out dx,al               ;Send command
  156.  
  157.             mov dx,03DAh            ;Read this port to reset
  158.             in al,dx                ;the Attribute Controller
  159.             mov dx,03C0h            ;Attribute Controller Port
  160.             mov al,33h              ;Horizontal Panning
  161.             out dx,al               ;Select register
  162.             xor al,al               ;Set Shift = 0
  163.             out dx,al               ;Send command
  164.  
  165.             mov dx,03D4h            ;CRT Controller Port
  166.             mov si,offset Data90x34 ;Offset of CRTC data
  167.             mov cx,17               ;17 words
  168.             rep outsw               ;Send data
  169.  
  170.             mov dx,03C4h            ;Sequencer Port
  171.             mov ax,0300h            ;Restart Sequencer
  172.             out dx,ax               ;Send command
  173.  
  174.             mov si,offset DataOE    ;Turning off Odd/Even...
  175.             mov dx,03C4h            ;SC port
  176.             outsw                   ;Send 2 words to SC port
  177.             outsw
  178.             mov dx,03CEh            ;GC port
  179.             outsw                   ;Send 3 words to GC port
  180.             outsw
  181.             outsw
  182.             push si                 ;Save SI
  183.  
  184.             mov si,1                ;Setting a 14-line Font.
  185.             xor di,di               ;Shifting up by 1
  186.             mov dx,256              ;All 256 chars
  187.             xor al,al               ;Zero AL
  188.  
  189. SS_sfont:   mov cx,14               ;14 bytes
  190.             seges rep movsb         ;Shift memory
  191.             mov cx,18               ;18 bytes
  192.             add si,cx               ;Next char slot
  193.             rep stosb               ;Clear excess
  194.             dec dx                  ;Loop back
  195.             jnz SS_sfont
  196.  
  197.             pop si                  ;Restoring Odd/Even...
  198.             mov dx,03C4h            ;SC port
  199.             outsw                   ;Send 2 words to SC port
  200.             outsw
  201.             mov dx,03CEh            ;GC port
  202.             outsw                   ;Send 3 words to GC port
  203.             outsw
  204.             outsw
  205.  
  206.             popa                    ;Restore registers
  207.             ret                     ;Return
  208.  
  209. Data90x34   dw 00011h               ;De-protect value
  210.             dw 06B00h,05901h,05A02h ;Horizontal CRTC data
  211.             dw 08E03h,06004h,08D05h
  212.             dw 00B06h,03E07h,04D09h ;Vertical CRTC data
  213.             dw 0EA10h,08C11h,0DF12h
  214.             dw 0E715h,00416h
  215.             dw 00C0Ah,00D0Bh        ;Initial cursor type
  216.  
  217. DataOE      dw 0402h,0704h,0204h    ;Odd/Even release and
  218.             dw 0005h,0406h          ;0A000h segment data
  219.             dw 0302h,0304h,0004h    ;Odd/Even restore data
  220.             dw 1005h,0606h
  221.  
  222. EndP        SetSize
  223.  
  224. ;****************** setcolor() -- Set text attribute
  225. ;void setcolor(int at);
  226.  
  227. Proc        setcolor
  228.  
  229.             push bp                 ;Set up stack frame
  230.             mov bp,sp
  231.  
  232.             push [bp+4]             ;Set attribute
  233.             pop [Attr]
  234.  
  235.             pop bp                  ;Delete stack frame
  236.             ret 2                   ;Return
  237.  
  238. EndP        setcolor
  239.  
  240. ;****************** getcolor() -- Get text attribute
  241. ;int getcolor(void);
  242.  
  243. Proc        getcolor
  244.  
  245.             mov ax,[Attr]           ;Get attribute
  246.             ret                     ;Return
  247.  
  248. EndP        getcolor
  249.  
  250. End
  251.  
  252. ~~~C_TXWIN
  253. Ideal
  254.  
  255. Include     "textmac.inc"           ;Include macros
  256. Include     "textdat.inc"           ;Include data
  257.  
  258. Public      setwin, clrwin, fbox
  259.  
  260. Model Tiny
  261. P186
  262. CodeSeg
  263.  
  264. ;****************** setwin() -- Set text window position, type
  265. ;void setwin(int x1, int y1, int x2, int y2, int rel);
  266.  
  267. Proc        setwin
  268.  
  269.             push bp                 ;Set up stack frame
  270.             mov bp,sp
  271.  
  272.             push [bp+12]            ;Set W_X1
  273.             pop [W_X1]
  274.             push [bp+10]            ;Set W_Y1
  275.             pop [W_Y1]
  276.             push [bp+8]             ;Set W_X2
  277.             pop [W_X2]
  278.             push [bp+6]             ;Set W_Y2
  279.             pop [W_Y2]
  280.             push [bp+4]             ;Set W_Rel
  281.             pop [W_Rel]
  282.  
  283.             pop bp                  ;Delete stack frame
  284.             ret 10                  ;Return
  285.  
  286. EndP        setwin
  287.  
  288. ;****************** clrwin() -- Clear window
  289. ;void clrwin(void);
  290.  
  291. Proc        clrwin
  292.  
  293.             pusha                   ;Save all registers
  294.  
  295.             mov ax,[W_X1]           ;Get values
  296.             mov bx,[W_Y1]
  297.             mov cx,[W_X2]
  298.             mov dx,[W_Y2]
  299.  
  300.             cmp [W_Rel],0           ;Relativity check
  301.             je clw_norel
  302.  
  303.             xor ax,ax               ;Adjust to window
  304.             xor bx,bx
  305.             sub cx,ax
  306.             sub dx,bx
  307.  
  308. clw_norel:  push ax bx cx dx ' '    ;fbox(W_X1, W_Y1,
  309.             call fbox               ;     W_X2, W_Y2, ' ');
  310.  
  311.             popa                    ;Restore registers
  312.             ret                     ;Return
  313.  
  314. EndP        clrwin
  315.  
  316. ;****************** fbox() -- Draw filled box
  317. ;void fbox(int x1, int y1, int x2, int y2, int ch);
  318.  
  319. Proc        fbox
  320.  
  321.             push bp                 ;Set up stack frame
  322.             mov bp,sp
  323.             pusha                   ;Save registers
  324.             push es
  325.  
  326.             mov es,[CurSeg]         ;ES = video memory
  327.  
  328.             mov ax,[bp+12]          ;Get values
  329.             mov bx,[bp+10]
  330.             mov cx,[bp+8]
  331.             mov dx,[bp+6]
  332.  
  333.             cmp [W_Rel],0           ;Relativity check
  334.             je fbx_norel
  335.  
  336.             add ax,[W_X1]           ;Adjust to window
  337.             add bx,[W_Y1]
  338.             add cx,[W_X1]
  339.             add dx,[W_Y1]
  340.  
  341. fbx_norel:  cmp ax,cx               ;X1 > X2?
  342.             jle fbx_xok
  343.             xchg ax,cx              ;Switch them
  344.  
  345. fbx_xok:    cmp bx,dx               ;Y1 > Y2?
  346.             jle fbx_yok
  347.             xchg bx,dx              ;Switch them
  348.  
  349. fbx_yok:    cmp ax,[W_X2]           ;X1 > W_X2?
  350.             jg fbx_bad
  351.             cmp cx,[W_X1]           ;X2 < W_X1?
  352.             jl fbx_bad
  353.             cmp bx,[W_Y2]           ;Y1 > W_Y2?
  354.             jg fbx_bad
  355.             cmp dx,[W_Y1]           ;Y2 < W_Y1?
  356.             jnl fbx_cx1
  357.  
  358. fbx_bad:    jmp fbx_done
  359.  
  360. fbx_cx1:    cmp ax,[W_X1]           ;X1 < W_X1?
  361.             jnl fbx_cx2
  362.             mov ax,[W_X1]           ;Fix X1
  363.  
  364. fbx_cx2:    cmp cx,[W_X2]           ;X2 > W_X2?
  365.             jng fbx_cy1
  366.             mov cx,[W_X2]           ;Fix X2
  367.  
  368. fbx_cy1:    cmp bx,[W_Y1]           ;Y1 < W_Y1?
  369.             jnl fbx_cy2
  370.             mov bx,[W_Y1]           ;Fix Y1
  371.  
  372. fbx_cy2:    cmp dx,[W_Y2]           ;Y2 > W_Y2?
  373.             jng fbx_cont
  374.             mov dx,[W_Y2]           ;Fix Y2
  375.  
  376. fbx_cont:   mov si,dx               ;SI = Y distance
  377.             sub si,bx
  378.             inc si
  379.             mov dx,cx               ;DX = X distance
  380.             sub dx,ax
  381.             inc dx
  382.  
  383.             mov cx,bx               ;BX, CX = X1, Y1
  384.             xchg bx,ax
  385.             mov al,[bp+4]           ;AL = char
  386.             mov ah,[byte Attr]      ;AH = attr
  387.  
  388. fbx_loop:   SET_ROW_CHA             ;Draw row
  389.             inc cx                  ;Next line
  390.             dec si                  ;Loop back
  391.             jnz fbx_loop
  392.  
  393. fbx_done:   pop es                  ;Restore registers
  394.             popa
  395.             pop bp                  ;Delete stack frame
  396.             ret 10                  ;Return
  397.  
  398. EndP        fbox
  399.  
  400. End
  401.  
  402. ~~~C_TXPAGE
  403. Ideal
  404.  
  405. Include     "textmac.inc"           ;Include macros
  406. Include     "textdat.inc"           ;Include data
  407.  
  408. Public      setpage, getpage
  409.  
  410. Model Tiny
  411. P186
  412. CodeSeg
  413.  
  414. ;****************** setpage() -- Set video page
  415. ;void setpage(int page);
  416.  
  417. Proc        setpage
  418.  
  419.             push bp                 ;Set up stack frame
  420.             mov bp,sp
  421.             pusha                   ;Save all registers
  422.  
  423.             mov ax,[bp+4]           ;AX = page number
  424.             and ax,7                ;Between 0 and 7
  425.  
  426.             shl ax,9                ;AX = segment
  427.             add ax,0A000h
  428.             mov [CurSeg],ax         ;Store segment
  429.  
  430.             mov dx,03D4h            ;CRTC port
  431.             shl ax,3                ;AH = high byte value
  432.             mov al,0Ch              ;Start Address High
  433.             out dx,ax               ;Send command
  434.  
  435.             popa                    ;Restore registers
  436.             pop bp                  ;Delete stack frame
  437.             ret 2                   ;Return
  438.  
  439. EndP        setpage
  440.  
  441. ;****************** getpage() -- Get video page
  442. ;int getpage(void);
  443.  
  444. Proc        getpage
  445.  
  446.             mov ax,[CurSeg]         ;Get segment pointer
  447.             sub ax,0A000h           ;Subtract video segment
  448.             shr ax,9                ;Divide by 512
  449.             ret                     ;Return
  450.  
  451. EndP        getpage
  452.  
  453. End
  454.  
  455. ~~~C_THLINE
  456. Ideal
  457.  
  458. Include     "textmac.inc"           ;Include macros
  459. Include     "textdat.inc"           ;Include data
  460.  
  461. Public      hline
  462.  
  463. Model Tiny
  464. P186
  465. CodeSeg
  466.  
  467. ;****************** hline() -- Draw horizontal line
  468. ;void hline(int x1, int x2, int y, int ch);
  469.  
  470. Proc        hline
  471.  
  472.             push bp                 ;Set up stack frame
  473.             mov bp,sp
  474.             push es                 ;Save registers
  475.             pusha
  476.             mov es,[CurSeg]         ;ES = video memory
  477.  
  478.             mov ax,[bp+10]          ;Get values
  479.             mov bx,[bp+6]
  480.             mov cx,[bp+8]
  481.  
  482.             cmp [W_Rel],0           ;Relativity check
  483.             je hl_norel
  484.  
  485.             add ax,[W_X1]           ;Adjust to window
  486.             add bx,[W_Y1]
  487.             add cx,[W_X1]
  488.  
  489. hl_norel:   cmp ax,cx               ;X1 > X2?
  490.             jle hl_xok
  491.             xchg ax,cx              ;Switch them
  492.  
  493. hl_xok:     cmp bx,[W_Y2]           ;Y > W_Y2?
  494.             jg hl_done
  495.             cmp bx,[W_Y1]           ;Y < W_Y1?
  496.             jl hl_done
  497.             cmp ax,[W_X2]           ;X1 > W_X2?
  498.             jg hl_done
  499.             cmp cx,[W_X1]           ;X2 < W_X1?
  500.             jl hl_done
  501.  
  502. hl_cx1:     cmp ax,[W_X1]           ;X1 < W_X1?
  503.             jnl hl_cx2
  504.             mov ax,[W_X1]           ;Fix X1
  505.  
  506. hl_cx2:     cmp cx,[W_X2]           ;X2 > W_X2?
  507.             jng hl_cont
  508.             mov cx,[W_X2]           ;Fix X2
  509.  
  510. hl_cont:    mov [bp+10],ax          ;Store end-points
  511.             mov [bp+6],bx
  512.             mov [bp+8],cx
  513.  
  514.             mov bx,[bp+10]          ;BX = X
  515.             mov cx,[bp+6]           ;CX = Y
  516.             mov dx,[bp+8]           ;DX = count
  517.             sub dx,bx
  518.             inc dx
  519.             mov al,[bp+4]           ;AL = char
  520.             mov ah,[byte Attr]      ;AH = attr
  521.  
  522.             SET_ROW_CHA             ;Draw row
  523.  
  524. hl_done:    popa                    ;Restore registers
  525.             pop es
  526.             pop bp                  ;Delete stack frame
  527.             ret 8                   ;Return
  528.  
  529. EndP        hline
  530.  
  531. End
  532.  
  533. ~~~C_TVLINE
  534. Ideal
  535.  
  536. Include     "textmac.inc"           ;Include macros
  537. Include     "textdat.inc"           ;Include data
  538.  
  539. Public      vline
  540.  
  541. Model Tiny
  542. P186
  543. CodeSeg
  544.  
  545. ;****************** vline() -- Draw vertical line
  546. ;void vline(int y1, int y2, int x, int ch);
  547.  
  548. Proc        vline
  549.  
  550.             push bp                 ;Set up stack frame
  551.             mov bp,sp
  552.             push es                 ;Save registers
  553.             pusha
  554.             mov es,[CurSeg]         ;ES = video memory
  555.  
  556.             mov ax,[bp+10]          ;Get values
  557.             mov bx,[bp+6]
  558.             mov cx,[bp+8]
  559.  
  560.             cmp [W_Rel],0           ;Relativity check
  561.             je vl_norel
  562.  
  563.             add ax,[W_Y1]           ;Adjust to window
  564.             add bx,[W_X1]
  565.             add cx,[W_Y1]
  566.  
  567. vl_norel:   cmp ax,cx               ;Y1 > Y2?
  568.             jle vl_yok
  569.             xchg ax,cx              ;Switch them
  570.  
  571. vl_yok:     cmp bx,[W_X2]           ;X > W_X2?
  572.             jg vl_done
  573.             cmp bx,[W_X1]           ;X < W_X1?
  574.             jl vl_done
  575.             cmp ax,[W_Y2]           ;Y1 > W_Y2?
  576.             jg vl_done
  577.             cmp cx,[W_Y1]           ;Y2 < W_Y1?
  578.             jl vl_done
  579.  
  580. vl_cy1:     cmp ax,[W_Y1]           ;Y1 < W_Y1?
  581.             jnl vl_cy2
  582.             mov ax,[W_Y1]           ;Fix Y1
  583.  
  584. vl_cy2:     cmp cx,[W_Y2]           ;Y2 > W_Y2?
  585.             jng vl_cont
  586.             mov cx,[W_Y2]           ;Fix Y2
  587.  
  588. vl_cont:    mov [bp+10],ax          ;Store end-points
  589.             mov [bp+6],bx
  590.             mov [bp+8],cx
  591.  
  592.             mov bx,[bp+6]           ;BX = X
  593.             mov cx,[bp+10]          ;CX = Y
  594.             mov dx,[bp+8]           ;DX = count
  595.             sub dx,cx
  596.             inc dx
  597.             mov al,[bp+4]           ;AL = char
  598.             mov ah,[byte Attr]      ;AH = attr
  599.  
  600.             SET_VROW_CHA            ;Draw row
  601.  
  602. vl_done:    popa                    ;Restore registers
  603.             pop es
  604.             pop bp                  ;Delete stack frame
  605.             ret 8                   ;Return
  606.  
  607. EndP        vline
  608.  
  609. End
  610.  
  611. ~~~C_TXBOX
  612. Ideal
  613.  
  614. Include     "textmac.inc"           ;Include macros
  615. Include     "textdat.inc"           ;Include data
  616.  
  617. Extrn       hline:near, vline:near
  618. Public      box
  619.  
  620. Model Tiny
  621. P186
  622. CodeSeg
  623.  
  624. ;****************** box() -- Draw box, single character
  625. ;void box(int x1, int y1, int x2, int y2, int ch);
  626.  
  627. Proc        box
  628.  
  629.             push bp                 ;Set up stack frame
  630.             mov bp,sp
  631.             pusha                   ;Save registers
  632.  
  633.             mov ax,[bp+12]          ;Get values
  634.             mov bx,[bp+10]
  635.             mov cx,[bp+8]
  636.             mov dx,[bp+6]
  637.  
  638.             cmp [W_Rel],0           ;Relativity check
  639.             je bx_norel
  640.  
  641.             add ax,[W_X1]           ;Adjust to window
  642.             add bx,[W_Y1]
  643.             add cx,[W_X1]
  644.             add dx,[W_Y1]
  645.  
  646. bx_norel:   mov [bp+12],ax          ;Store values
  647.             mov [bp+10],bx
  648.             mov [bp+8],cx
  649.             mov [bp+6],dx
  650.  
  651.             mov si,[bp+4]           ;SI = char
  652.  
  653.             push ax bx cx si        ;Draw top line
  654.             call hline
  655.             push ax cx dx si        ;Draw bottom line
  656.             call hline
  657.             push bx dx ax si        ;Draw left line
  658.             call vline
  659.             push bx dx cx si        ;Draw right line
  660.             call vline
  661.  
  662.             popa                    ;Restore registers
  663.             pop bp                  ;Delete stack frame
  664.             ret 10                  ;Return
  665.  
  666. EndP        box
  667.  
  668. End
  669.  
  670. ~~~C_STYBOX
  671. Ideal
  672.  
  673. Include     "textmac.inc"           ;Include macros
  674. Include     "textdat.inc"           ;Include data
  675.  
  676. Extrn       hline:near, vline:near
  677. Public      hsline, vsline, sbox
  678.  
  679. Model Tiny
  680. P186
  681. CodeSeg
  682.  
  683. STYLEdata   db '      '             ;Box style data: (0 = blank)
  684.             db '─│┌┐└┘'             ;┌─┬─┐ ╔═╦═╗ ╒═╤═╕ ╓─╥─╖
  685.             db '═║╔╗╚╝'             ;├─┼─┤ ╠═╬═╣ ╞═╪═╡ ╟─╫─╢
  686.             db '═│╒╕╘╛'             ;└─┴─┘ ╚═╩═╝ ╘═╧═╛ ╙─╨─╜
  687.             db '─║╓╖╙╜'             ;  1     2     3     4
  688.  
  689. ;****************** sbox() -- Draw box, with style
  690. ;void sbox(int x1, int y1, int x2, int y2, int style);
  691.  
  692. Proc        sbox
  693.  
  694.             push bp                 ;Set up stack frame
  695.             mov bp,sp
  696.             pusha                   ;Save registers
  697.             push es
  698.  
  699.             mov es,[CurSeg]         ;ES = video memory
  700.  
  701.             mov ax,[bp+12]          ;Get values
  702.             mov bx,[bp+10]
  703.             mov cx,[bp+8]
  704.             mov dx,[bp+6]
  705.  
  706.             cmp [W_Rel],0           ;Relativity check
  707.             je sbx_norel
  708.  
  709.             add ax,[W_X1]           ;Adjust to window
  710.             add bx,[W_Y1]
  711.             add cx,[W_X1]
  712.             add dx,[W_Y1]
  713.  
  714. sbx_norel:  mov [bp+12],ax          ;Store values
  715.             mov [bp+10],bx
  716.             mov [bp+8],cx
  717.             mov [bp+6],dx
  718.  
  719.             mov si,[bp+4]           ;SI = style
  720.  
  721.             inc ax                  ;Set up for hsline
  722.             dec cx
  723.  
  724.             push ax cx bx si        ;Draw top line
  725.             call hsline
  726.             push ax cx dx si        ;Draw bottom line
  727.             call hsline
  728.  
  729.             dec ax                  ;Set up for vsline
  730.             inc cx
  731.             inc bx
  732.             dec dx
  733.  
  734.             push bx dx ax si        ;Draw left line
  735.             call vsline
  736.             push bx dx cx si        ;Draw right line
  737.             call vsline
  738.  
  739.             mov bx,[bp+4]           ;AL = TLC char
  740.             imul bx,6
  741.             mov al,[STYLEdata+bx+2]
  742.  
  743.             mov bx,[bp+12]          ;Draw TLC . . .
  744.             mov cx,[bp+10]
  745.  
  746.             cmp cx,[W_Y1]           ;Clip character
  747.             jl sbx_skip2
  748.             cmp cx,[W_Y2]
  749.             jg sbx_skip2
  750.             cmp bx,[W_X1]
  751.             jl sbx_skip1
  752.             cmp bx,[W_X2]
  753.             jg sbx_skip1
  754.  
  755.             mov ah,[byte Attr]      ;AH = attr
  756.             SET_CHA                 ;Draw character
  757.  
  758. sbx_skip1:  mov bx,[bp+4]           ;AL = TRC char
  759.             imul bx,6
  760.             mov al,[STYLEdata+bx+3]
  761.  
  762.             mov bx,[bp+8]           ;Draw TRC . . .
  763.             mov cx,[bp+10]
  764.  
  765.             cmp bx,[W_X1]           ;Clip character
  766.             jl sbx_skip2
  767.             cmp bx,[W_X2]
  768.             jg sbx_skip2
  769.  
  770.             mov ah,[byte Attr]      ;AH = attr
  771.             SET_CHA                 ;Draw character
  772.  
  773. sbx_skip2:  mov bx,[bp+4]           ;AL = LLC char
  774.             imul bx,6
  775.             mov al,[STYLEdata+bx+4]
  776.  
  777.             mov bx,[bp+12]          ;Draw LLC . . .
  778.             mov cx,[bp+6]
  779.  
  780.             cmp cx,[W_Y1]           ;Clip character
  781.             jl sbx_done
  782.             cmp cx,[W_Y2]
  783.             jg sbx_done
  784.             cmp bx,[W_X1]
  785.             jl sbx_skip3
  786.             cmp bx,[W_X2]
  787.             jg sbx_skip3
  788.  
  789.             mov ah,[byte Attr]      ;AH = attr
  790.             SET_CHA                 ;Draw character
  791.  
  792. sbx_skip3:  mov bx,[bp+4]           ;AL = LRC char
  793.             imul bx,6
  794.             mov al,[STYLEdata+bx+5]
  795.  
  796.             mov bx,[bp+8]           ;Draw LRC . . .
  797.             mov cx,[bp+6]
  798.  
  799.             cmp bx,[W_X1]           ;Clip character
  800.             jl sbx_done
  801.             cmp bx,[W_X2]
  802.             jg sbx_done
  803.  
  804.             mov ah,[byte Attr]      ;AH = attr
  805.             SET_CHA                 ;Draw character
  806.  
  807. sbx_done:   pop es                  ;Restore registers
  808.             popa
  809.             pop bp                  ;Delete stack frame
  810.             ret 10                  ;Return
  811.  
  812. EndP        sbox
  813.  
  814. ;****************** hsline() -- Draw horizontal style line
  815. ;void hsline(int x1, int x2, int y, int style);
  816.  
  817. Proc        hsline
  818.  
  819.             push bp                 ;Set up stack frame
  820.             mov bp,sp
  821.             pusha                   ;Save all registers
  822.  
  823.             mov bx,[bp+4]           ;AL = HL char
  824.             imul bx,6
  825.             mov al,[STYLEdata+bx]
  826.             xor ah,ah
  827.  
  828.             push [bp+10] [bp+8]     ;Push args
  829.             push [bp+6] ax
  830.             call hline              ;Draw line
  831.  
  832.             popa                    ;Restore registers
  833.             pop bp                  ;Delete stack frame
  834.             ret 8                   ;Return
  835.  
  836. EndP        hsline
  837.  
  838. ;****************** vsline() -- Draw vertical style line
  839. ;void vsline(int y1, int y2, int x, int style);
  840.  
  841. Proc        vsline
  842.  
  843.             push bp                 ;Set up stack frame
  844.             mov bp,sp
  845.             pusha                   ;Save all registers
  846.  
  847.             mov bx,[bp+4]           ;AL = VL char
  848.             imul bx,6
  849.             mov al,[STYLEdata+bx+1]
  850.             xor ah,ah
  851.  
  852.             push [bp+10] [bp+8]     ;Push args
  853.             push [bp+6] ax
  854.             call vline              ;Draw line
  855.  
  856.             popa                    ;Restore registers
  857.             pop bp                  ;Delete stack frame
  858.             ret 8                   ;Return
  859.  
  860. EndP        vsline
  861.  
  862. End
  863.  
  864. ~~~C_TEXCUR
  865. Ideal
  866.  
  867. Include     "textmac.inc"           ;Include macros
  868. Include     "textdat.inc"           ;Include data
  869.  
  870. Public      gotoxy, getx, gety, setctype, getctype
  871.  
  872. Model Tiny
  873. P186
  874. CodeSeg
  875.  
  876. ;****************** gotoxy() -- Set cursor position
  877. ;void gotoxy(int x, int y);
  878.  
  879. Proc        gotoxy
  880.  
  881.             push bp                 ;Set up stack frame
  882.             mov bp,sp
  883.             pusha                   ;Save all registers
  884.  
  885.             mov ax,[bp+6]           ;Get values
  886.             mov bx,[bp+4]
  887.  
  888.             cmp [W_Rel],0           ;Relativity check
  889.             je xy_norel
  890.  
  891.             add ax,[W_X1]           ;Adjust to window
  892.             add bx,[W_Y1]
  893.  
  894. xy_norel:   cmp ax,[W_X1]           ;Clip to window
  895.             jl xy_done
  896.             cmp ax,[W_X2]
  897.             jg xy_done
  898.             cmp bx,[W_Y1]
  899.             jl xy_done
  900.             cmp bx,[W_Y2]
  901.             jg xy_done
  902.  
  903.             shl bx,7                ;Get CRTC address
  904.             add bx,ax
  905.  
  906.             mov dx,03D4h            ;CRTC port
  907.             mov al,0Eh              ;Cursor Loc High
  908.             mov ah,bh               ;Set value
  909.             out dx,ax
  910.             inc ax                  ;Cursor Loc Low
  911.             mov ah,bl               ;Set value
  912.             out dx,ax
  913.  
  914. xy_done:    popa                    ;Restore registers
  915.             pop bp                  ;Delete stack frame
  916.             ret 4                   ;Return
  917.  
  918. EndP        gotoxy
  919.  
  920. ;****************** getx() -- Get cursor X position
  921. ;int getx(void);
  922.  
  923. Proc        getx
  924.  
  925.             push dx                 ;Save DX
  926.  
  927.             mov dx,03D4h            ;CRTC port
  928.             mov al,0Fh              ;Cursor Loc Low
  929.             out dx,al               ;Set register
  930.             inc dx                  ;Data port
  931.             in al,dx                ;Read value
  932.  
  933.             and ax,127              ;Get X position
  934.  
  935.             cmp [W_Rel],0           ;Relativity check
  936.             je gx_done
  937.             sub ax,[W_X1]           ;Adjust to window
  938.  
  939. gx_done:    pop dx                  ;Restore DX
  940.             ret                     ;Return
  941.  
  942. EndP        getx
  943.  
  944. ;****************** gety() -- Get cursor Y position
  945. ;int gety(void);
  946.  
  947. Proc        gety
  948.  
  949.             push dx                 ;Save DX
  950.  
  951.             mov dx,03D4h            ;CRTC port
  952.             mov al,0Eh              ;Cursor Loc High
  953.             out dx,al               ;Set register
  954.             inc dx                  ;Data port
  955.             in al,dx                ;Read value
  956.             mov ah,al
  957.             dec dx                  ;Index port
  958.             mov al,0Fh              ;Cursor Loc Low
  959.             out dx,al               ;Set register
  960.             inc dx                  ;Data port
  961.             in al,dx                ;Read value
  962.  
  963.             shr ax,7                ;Get Y position
  964.             and ax,127
  965.  
  966.             cmp [W_Rel],0           ;Relativity check
  967.             je gy_done
  968.             sub ax,[W_Y1]           ;Adjust to window
  969.  
  970. gy_done:    pop dx                  ;Restore DX
  971.             ret                     ;Return
  972.  
  973. EndP        gety
  974.  
  975. ;****************** setctype() -- Set cursor type
  976. ;void setctype(int type);
  977.  
  978. Proc        setctype
  979.  
  980.             push bp                 ;Set up stack frame
  981.             mov bp,sp
  982.             pusha                   ;Save all registers
  983.  
  984.             mov bx,[bp+4]           ;Get type
  985.  
  986.             mov dx,03D4h            ;CRTC port
  987.             mov al,0Ah              ;Cursor Start
  988.             mov ah,bh               ;Set value
  989.             out dx,ax
  990.             inc ax                  ;Cursor End
  991.             mov ah,bl               ;Set value
  992.             out dx,ax
  993.  
  994.             popa                    ;Restore registers
  995.             pop bp                  ;Delete stack frame
  996.             ret 2                   ;Return
  997.  
  998. EndP        setctype
  999.  
  1000. ;****************** getctype() -- Get cursor type
  1001. ;int getctype(void);
  1002.  
  1003. Proc        getctype
  1004.  
  1005.             push dx                 ;Save DX
  1006.  
  1007.             mov dx,03D4h            ;CRTC port
  1008.             mov al,0Ah              ;Cursor Start
  1009.             out dx,al               ;Set register
  1010.             inc dx                  ;Data port
  1011.             in al,dx                ;Read value
  1012.             mov ah,al
  1013.             dec dx                  ;Index port
  1014.             mov al,0Bh              ;Cursor End
  1015.             out dx,al               ;Set register
  1016.             inc dx                  ;Data port
  1017.             in al,dx                ;Read value
  1018.  
  1019.             pop dx                  ;Restore DX
  1020.             ret                     ;Return
  1021.  
  1022. EndP        getctype
  1023.  
  1024. End
  1025.  
  1026. ~~~C_TPUTS
  1027. Ideal
  1028.  
  1029. Include     "textmac.inc"           ;Include macros
  1030. Include     "textdat.inc"           ;Include data
  1031.  
  1032. Public      tputs
  1033.  
  1034. Model Tiny
  1035. P186
  1036. CodeSeg
  1037.  
  1038. ;****************** tputs() -- Put string
  1039. ;void tputs(int x, int y, char *str);
  1040.  
  1041. Proc        tputs
  1042.  
  1043.             push bp                 ;Set up stack frame
  1044.             mov bp,sp
  1045.             push es                 ;Save registers
  1046.             pusha
  1047.             mov es,[CurSeg]         ;ES = video memory
  1048.  
  1049.             mov ax,[bp+8]           ;Get values
  1050.             mov bx,[bp+6]
  1051.  
  1052.             cmp [W_Rel],0           ;Relativity check
  1053.             je ps_norel
  1054.  
  1055.             add ax,[W_X1]           ;Adjust to window
  1056.             add bx,[W_Y1]
  1057.             mov [bp+8],ax
  1058.             mov [bp+6],bx
  1059.  
  1060. ps_norel:   cmp bx,[W_Y1]           ;Y < W_Y1?
  1061.             jl ps_done
  1062.             cmp bx,[W_Y2]           ;Y > W_Y2?
  1063.             jg ps_done
  1064.             cmp ax,[W_X2]           ;X > W_X2?
  1065.             jg ps_done
  1066.  
  1067.             shl bx,8                ;DI = offset
  1068.             add bx,ax
  1069.             add bx,ax
  1070.             mov di,bx
  1071.  
  1072.             mov si,[bp+4]           ;SI = string
  1073.             mov bx,[bp+8]           ;BX = X
  1074.             mov cx,[W_X1]           ;CX = W_X1
  1075.             mov dx,[W_X2]           ;DX = W_X2
  1076.             mov ah,[byte Attr]      ;AH = color
  1077.  
  1078. ps_loop:    lodsb                   ;Load char
  1079.             test al,al              ;Null, done
  1080.             je ps_done
  1081.             cmp bx,cx               ;Off left, loop
  1082.             jl ps_lb
  1083.             cmp bx,dx
  1084.             jg ps_done              ;Off right, quit
  1085.  
  1086.             mov [es:di],ax          ;Write char
  1087.  
  1088. ps_lb:      inc di                  ;Advance pointer
  1089.             inc di
  1090.             inc bx                  ;Advance X
  1091.             jmp ps_loop             ;Loop back
  1092.  
  1093. ps_done:    popa                    ;Restore registers
  1094.             pop es bp               ;Delete stack frame
  1095.             ret 6                   ;Return
  1096.  
  1097. EndP        tputs
  1098.  
  1099. End
  1100.  
  1101. ~~~C_TPRINT
  1102. Ideal
  1103.  
  1104. Extrn       sprintf:near,tputs:near,allocmem:near,freemem:near
  1105. Public      tprintf
  1106.  
  1107. Model Tiny
  1108. CodeSeg
  1109. P186
  1110.  
  1111. ;****************** tprintf() -- Print formatted string
  1112. ;void tprintf(int x, int y, char *fmt, void *args);
  1113.  
  1114. x           equ bp+10
  1115. y           equ bp+8
  1116. fmt         equ bp+6
  1117. args        equ bp+4
  1118.  
  1119. Proc        tprintf
  1120.  
  1121.             push bp                 ;Set up stack frame
  1122.             mov bp,sp
  1123.             pusha                   ;Save all registers
  1124.  
  1125.             push 400                ;Allocate a 400 byte buffer
  1126.             call allocmem
  1127.             test ax,ax              ;Out of memory?
  1128.             jz tp_done
  1129.  
  1130.             xchg bx,ax              ;BX = buffer
  1131.             push bx [fmt] [args]    ;sprintf() into buffer
  1132.             call sprintf
  1133.  
  1134.             push [x] [y] bx         ;Print string to screen
  1135.             call tputs
  1136.  
  1137.             push bx
  1138.             call freemem            ;Free memory
  1139.  
  1140. tp_done:    popa                    ;Restore registers
  1141.             pop bp                  ;Delete stack frame
  1142.             ret 8                   ;Return
  1143.  
  1144. EndP        tprintf
  1145.  
  1146. End
  1147.  
  1148. ~~~C_TXCHAR
  1149. Ideal
  1150.  
  1151. Include     "textmac.inc"           ;Include macros
  1152. Include     "textdat.inc"           ;Include data
  1153.  
  1154. Public      setch, setat, setcha, readcha
  1155.  
  1156. Model Tiny
  1157. P186
  1158. CodeSeg
  1159.  
  1160. ;****************** setch() -- Write character
  1161. ;void setch(int x, int y, int ch);
  1162.  
  1163. Proc        setch
  1164.  
  1165.             push bp                 ;Set up stack frame
  1166.             mov bp,sp
  1167.             pusha                   ;Save all registers
  1168.             push es
  1169.             mov es,[CurSeg]         ;ES = video memory
  1170.  
  1171.             mov bx,[bp+8]           ;Get values
  1172.             mov cx,[bp+6]
  1173.  
  1174.             cmp [W_Rel],0           ;Relativity check
  1175.             je sch_norel
  1176.  
  1177.             add bx,[W_X1]           ;Adjust to window
  1178.             add cx,[W_Y1]
  1179.  
  1180. sch_norel:  cmp bx,[W_X1]           ;X < W_X1?
  1181.             jl sch_done
  1182.             cmp bx,[W_X2]           ;X > W_X2?
  1183.             jg sch_done
  1184.             cmp cx,[W_Y1]           ;Y < W_Y1?
  1185.             jl sch_done
  1186.             cmp cx,[W_Y2]           ;Y > W_Y2?
  1187.             jg sch_done
  1188.  
  1189.             mov al,[bp+4]           ;AL = char
  1190.             SET_CH                  ;Write char
  1191.  
  1192. sch_done:   pop es                  ;Restore registers
  1193.             popa
  1194.             pop bp                  ;Delete stack frame
  1195.             ret 6                   ;Return
  1196.  
  1197. EndP        setch
  1198.  
  1199. ;****************** setat() -- Write attribute
  1200. ;void setat(int x, int y, int at);
  1201.  
  1202. Proc        setat
  1203.  
  1204.             push bp                 ;Set up stack frame
  1205.             mov bp,sp
  1206.             pusha                   ;Save all registers
  1207.             push es
  1208.             mov es,[CurSeg]         ;ES = video memory
  1209.  
  1210.             mov bx,[bp+8]           ;Get values
  1211.             mov cx,[bp+6]
  1212.  
  1213.             cmp [W_Rel],0           ;Relativity check
  1214.             je sa_norel
  1215.  
  1216.             add bx,[W_X1]           ;Adjust to window
  1217.             add cx,[W_Y1]
  1218.  
  1219. sa_norel:   cmp bx,[W_X1]           ;X < W_X1?
  1220.             jl sa_done
  1221.             cmp bx,[W_X2]           ;X > W_X2?
  1222.             jg sa_done
  1223.             cmp cx,[W_Y1]           ;Y < W_Y1?
  1224.             jl sa_done
  1225.             cmp cx,[W_Y2]           ;Y > W_Y2?
  1226.             jg sa_done
  1227.  
  1228.             mov al,[bp+4]           ;AL = attr.
  1229.             SET_AT                  ;Write attr.
  1230.  
  1231. sa_done:    pop es                  ;Restore registers
  1232.             popa
  1233.             pop bp                  ;Delete stack frame
  1234.             ret 6                   ;Return
  1235.  
  1236. EndP        setat
  1237.  
  1238. ;****************** setcha() -- Write char, attr.
  1239. ;void setcha(int x, int y, int ch, int at);
  1240.  
  1241. Proc        setcha
  1242.  
  1243.             push bp                 ;Set up stack frame
  1244.             mov bp,sp
  1245.             pusha                   ;Save all registers
  1246.             push es
  1247.             mov es,[CurSeg]         ;ES = video memory
  1248.  
  1249.             mov bx,[bp+10]          ;Get values
  1250.             mov cx,[bp+8]
  1251.  
  1252.             cmp [W_Rel],0           ;Relativity check
  1253.             je sb_norel
  1254.  
  1255.             add bx,[W_X1]           ;Adjust to window
  1256.             add cx,[W_Y1]
  1257.  
  1258. sb_norel:   cmp bx,[W_X1]           ;X < W_X1?
  1259.             jl sb_done
  1260.             cmp bx,[W_X2]           ;X > W_X2?
  1261.             jg sb_done
  1262.             cmp cx,[W_Y1]           ;Y < W_Y1?
  1263.             jl sb_done
  1264.             cmp cx,[W_Y2]           ;Y > W_Y2?
  1265.             jg sb_done
  1266.  
  1267.             mov al,[bp+6]           ;AL = char
  1268.             mov ah,[bp+4]           ;AH = attr.
  1269.             SET_CHA                 ;Write char, attr.
  1270.  
  1271. sb_done:    pop es                  ;Restore registers
  1272.             popa
  1273.             pop bp                  ;Delete stack frame
  1274.             ret 8                   ;Return
  1275.  
  1276. EndP        setcha
  1277.  
  1278. ;****************** readcha() -- Read character and attribute
  1279. ;int readcha(int x, int y);
  1280.  
  1281. Proc        readcha
  1282.  
  1283.             push bp                 ;Set up stack frame
  1284.             mov bp,sp
  1285.             push es bx              ;Save registers
  1286.             mov es,[CurSeg]         ;ES = video memory
  1287.  
  1288.             mov ax,[bp+6]           ;Get values
  1289.             mov bx,[bp+4]
  1290.  
  1291.             cmp [W_Rel],0           ;Relativity check
  1292.             je rc_norel
  1293.  
  1294.             add ax,[W_X1]           ;Adjust to window
  1295.             add bx,[W_Y1]
  1296.  
  1297. rc_norel:   shl bx,8                ;Get offset
  1298.             add bx,ax
  1299.             add bx,ax
  1300.             mov ax,[es:bx]          ;Read char/attr
  1301.  
  1302.             pop bx es               ;Restore registers
  1303.             pop bp                  ;Delete stack frame
  1304.             ret 4                   ;Return
  1305.  
  1306. EndP        readcha
  1307.  
  1308. End
  1309.  
  1310. ~~~C_GPTEXT
  1311. Ideal
  1312.  
  1313. Include     "textmac.inc"           ;Include macros
  1314. Include     "textdat.inc"           ;Include data
  1315.  
  1316. Public      gettext, puttext
  1317.  
  1318. Model Tiny
  1319. P186
  1320. CodeSeg
  1321.  
  1322. ;****************** gettext() -- Get text image
  1323. ;void gettext(void *buf, int x1, int y1, int x2, int y2);
  1324.  
  1325. Proc        gettext
  1326.  
  1327.             push bp                 ;Set up stack frame
  1328.             mov bp,sp
  1329.             push ds es              ;Save registers
  1330.             pusha
  1331.  
  1332.             mov ds,[CurSeg]         ;DS = video memory
  1333.  
  1334.             push cs                 ;ES:DI = text buffer
  1335.             pop es
  1336.             mov di,[bp+12]
  1337.  
  1338.             mov ax,[bp+10]          ;Get values
  1339.             mov bx,[bp+8]
  1340.             mov cx,[bp+6]
  1341.             mov dx,[bp+4]
  1342.  
  1343.             cmp [cs:W_Rel],0        ;Relativity check
  1344.             je gt_norel
  1345.  
  1346.             add ax,[cs:W_X1]        ;Adjust to window
  1347.             add bx,[cs:W_Y1]
  1348.             add cx,[cs:W_X1]
  1349.             add dx,[cs:W_Y1]
  1350.  
  1351. gt_norel:   cmp ax,cx               ;Put them in order
  1352.             jle $+3
  1353.             xchg ax,cx
  1354.             cmp bx,dx
  1355.             jle $+4
  1356.             xchg bx,dx
  1357.  
  1358.             mov [bp+10],ax          ;Save values
  1359.             mov [bp+8],bx
  1360.             mov [bp+6],cx
  1361.             mov [bp+4],dx
  1362.  
  1363.             mov si,[bp+8]           ;SI = source offset
  1364.             mov ax,[bp+10]
  1365.             shl si,8
  1366.             add si,ax
  1367.             add si,ax
  1368.  
  1369.             mov dx,[bp+6]           ;DX = X distance
  1370.             sub dx,[bp+10]
  1371.             inc dx
  1372.             mov bx,[bp+4]           ;BX = Y distance
  1373.             sub bx,[bp+8]
  1374.             inc bx
  1375.  
  1376.             mov ax,dx               ;Store size
  1377.             stosw
  1378.             mov ax,bx
  1379.             stosw
  1380.  
  1381.             mov ax,256              ;AX = offset adjust
  1382.             sub ax,dx
  1383.             sub ax,dx
  1384.  
  1385. gt_loop:    mov cx,dx               ;Move line
  1386.             rep movsw
  1387.             add si,ax               ;Advance pointers
  1388.             dec bx                  ;Loop back
  1389.             jnz gt_loop
  1390.  
  1391. gt_done:    popa                    ;Restore registers
  1392.             pop es ds
  1393.             pop bp                  ;Delete stack frame
  1394.             ret 10                  ;Return
  1395.  
  1396. EndP        gettext
  1397.  
  1398. ;****************** puttext() -- Put text image
  1399. ;void puttext(void *buf, int x, int y);
  1400.  
  1401. Proc        puttext
  1402.  
  1403.             push bp                 ;Set up stack frame
  1404.             mov bp,sp
  1405.             push es                 ;Save registers
  1406.             pusha
  1407.  
  1408.             mov es,[CurSeg]         ;ES = video memory
  1409.  
  1410.             mov si,[bp+8]           ;SI = text buffer
  1411.  
  1412.             mov ax,[bp+6]           ;Get values
  1413.             mov bx,[bp+4]
  1414.  
  1415.             cmp [W_Rel],0           ;Relativity check
  1416.             je pt_norel
  1417.  
  1418.             add ax,[W_X1]           ;Adjust to window
  1419.             add bx,[W_Y1]
  1420.  
  1421. pt_norel:   mov [bp+6],ax           ;Save values
  1422.             mov [bp+4],bx
  1423.  
  1424.             lodsw                   ;CX = X distance
  1425.             xchg cx,ax
  1426.             lodsw                   ;DX = Y distance
  1427.             xchg dx,ax
  1428.  
  1429.             mov ax,[bp+6]           ;Restore AX
  1430.  
  1431.             add cx,ax               ;CX, DX = X2, Y2
  1432.             add dx,bx
  1433.             dec cx
  1434.             dec dx
  1435.  
  1436.             cmp ax,[W_X1]           ;Clip to window
  1437.             jl pt_done
  1438.             cmp bx,[W_Y1]
  1439.             jl pt_done
  1440.             cmp cx,[W_X2]
  1441.             jg pt_done
  1442.             cmp dx,[W_Y2]
  1443.             jg pt_done
  1444.  
  1445.             inc cx                  ;Restore distances
  1446.             sub cx,ax
  1447.             inc dx
  1448.             sub dx,bx
  1449.             mov bx,dx               ;DX = X distance
  1450.             mov dx,cx               ;BX = Y distance
  1451.  
  1452.             mov di,[bp+4]           ;DI = dest. offset
  1453.             mov ax,[bp+6]
  1454.             shl di,8
  1455.             add di,ax
  1456.             add di,ax
  1457.  
  1458.             mov ax,256              ;AX = offset adjust
  1459.             sub ax,dx
  1460.             sub ax,dx
  1461.  
  1462. pt_loop:    mov cx,dx               ;Move line
  1463.             rep movsw
  1464.             add di,ax               ;Advance pointers
  1465.             dec bx                  ;Loop back
  1466.             jnz pt_loop
  1467.  
  1468. pt_done:    popa                    ;Restore registers
  1469.             pop es
  1470.             pop bp                  ;Delete stack frame
  1471.             ret 6                   ;Return
  1472.  
  1473. EndP        puttext
  1474.  
  1475. End
  1476.  
  1477. ~~~C_MTEXT
  1478. Ideal
  1479.  
  1480. Include     "textmac.inc"           ;Include macros
  1481. Include     "textdat.inc"           ;Include data
  1482.  
  1483. Public      movetext
  1484.  
  1485. Model Tiny
  1486. P186
  1487. CodeSeg
  1488.  
  1489. ;****************** movetext() -- Move window of text
  1490. ;void movetext(int x1, int y1, int x2, int y2, int x, int y);
  1491.  
  1492. Proc        movetext
  1493.  
  1494.             push bp                 ;Set up stack frame
  1495.             mov bp,sp
  1496.             pusha                   ;Save registers
  1497.             push ds es
  1498.  
  1499.             mov ax,[CurSeg]         ;DS, ES = video memory
  1500.             mov ds,ax
  1501.             mov es,ax
  1502.  
  1503.             mov ax,[bp+14]          ;Get values
  1504.             mov bx,[bp+12]
  1505.             mov cx,[bp+10]
  1506.             mov dx,[bp+8]
  1507.             mov si,[bp+6]
  1508.             mov di,[bp+4]
  1509.  
  1510.             cmp ax,cx               ;Put them in order
  1511.             jle $+3
  1512.             xchg ax,cx
  1513.             cmp bx,dx
  1514.             jle $+4
  1515.             xchg bx,dx
  1516.  
  1517.             mov [bp+14],ax          ;Save values
  1518.             mov [bp+12],bx
  1519.             mov [bp+10],cx
  1520.             mov [bp+8],dx
  1521.             mov [bp+6],si
  1522.             mov [bp+4],di
  1523.  
  1524.             mov ax,[bp+12]          ;Greater offset, move from end
  1525.             cmp ax,[bp+4]           ;Lesser offset, move from start
  1526.             jl mw_rev               ;Same offset, do nothing
  1527.             jg mw_for
  1528.             mov ax,[bp+14]
  1529.             cmp ax,[bp+6]
  1530.             jl mw_rev
  1531.             jg mw_for
  1532.             jmp mw_done
  1533.  
  1534. mw_for:     mov si,[bp+12]          ;SI = source offset
  1535.             mov ax,[bp+14]
  1536.             shl si,8
  1537.             add si,ax
  1538.             add si,ax
  1539.  
  1540.             mov di,[bp+4]           ;DI = dest. offset
  1541.             mov ax,[bp+6]
  1542.             shl di,8
  1543.             add di,ax
  1544.             add di,ax
  1545.  
  1546.             mov dx,[bp+10]          ;DX = X distance
  1547.             sub dx,[bp+14]
  1548.             inc dx
  1549.             mov bx,[bp+8]           ;BX = Y distance
  1550.             sub bx,[bp+12]
  1551.             inc bx
  1552.  
  1553.             mov ax,256              ;AX = offset adjust
  1554.             sub ax,dx
  1555.             sub ax,dx
  1556.  
  1557. mw_floop:   mov cx,dx               ;Move line
  1558.             rep movsw
  1559.             add si,ax               ;Advance pointers
  1560.             add di,ax
  1561.             dec bx                  ;Loop back
  1562.             jnz mw_floop
  1563.             jmp mw_done
  1564.  
  1565. mw_rev:     mov si,[bp+12]          ;SI = source offset
  1566.             mov ax,[bp+14]
  1567.             shl si,8
  1568.             add si,ax
  1569.             add si,ax
  1570.  
  1571.             mov di,[bp+4]           ;DI = dest. offset
  1572.             mov ax,[bp+6]
  1573.             shl di,8
  1574.             add di,ax
  1575.             add di,ax
  1576.  
  1577.             mov dx,[bp+10]          ;DX = X distance
  1578.             sub dx,[bp+14]
  1579.             mov bx,[bp+8]           ;BX = Y distance
  1580.             sub bx,[bp+12]
  1581.  
  1582.             mov ax,bx               ;Move offsets to end
  1583.             shl ax,8
  1584.             add ax,dx
  1585.             add ax,dx
  1586.             add si,ax
  1587.             add di,ax
  1588.  
  1589.             inc dx                  ;Fix distances
  1590.             inc bx
  1591.  
  1592.             mov ax,256              ;AX = offset adjust
  1593.             sub ax,dx
  1594.             sub ax,dx
  1595.             std                     ;Direction is reverse
  1596.  
  1597. mw_rloop:   mov cx,dx               ;Move line
  1598.             rep movsw
  1599.             sub si,ax               ;Advance pointers
  1600.             sub di,ax
  1601.             dec bx                  ;Loop back
  1602.             jnz mw_rloop
  1603.  
  1604. mw_done:    cld                     ;Clear direction flag
  1605.             pop es ds               ;Restore registers
  1606.             popa
  1607.             pop bp                  ;Delete stack frame
  1608.             ret 12                  ;Return
  1609.  
  1610. EndP        movetext
  1611.  
  1612. End
  1613.  
  1614. ~~~C_SCROLL
  1615. Ideal
  1616.  
  1617. Include     "textmac.inc"           ;Include macros
  1618. Include     "textdat.inc"           ;Include data
  1619.  
  1620. Extrn       movetext:near, hline:near
  1621. Extrn       vline:near, clrwin:near
  1622. Public      scroll
  1623.  
  1624. Model Tiny
  1625. P186
  1626. CodeSeg
  1627.  
  1628. ;****************** scroll() -- Scroll window
  1629. ;void scroll(int dir);
  1630.  
  1631. Proc        scroll
  1632.  
  1633.             push bp                 ;Set up stack frame
  1634.             mov bp,sp
  1635.             pusha                   ;Save registers
  1636.  
  1637.             mov bx,[bp+4]           ;Get direction
  1638.             and bx,3                ;Jump to routine
  1639.             add bx,bx
  1640.             jmp [ScTable+bx]
  1641.  
  1642. sc_up:      mov ax,[W_Y1]           ;Window one line?
  1643.             cmp ax,[W_Y2]
  1644.             jne sc_cont1
  1645.             jmp sc_tiny
  1646.  
  1647. sc_cont1:   inc ax
  1648.             push [W_X1] ax          ;Push args
  1649.             push [W_X2] [W_Y2]
  1650.             push [W_X1] [W_Y1]
  1651.             call movetext           ;Scroll up
  1652.  
  1653.             push [W_X1] [W_X2]      ;Clear bottom line
  1654.             push [W_Y2] ' '
  1655.             call hline
  1656.             jmp sc_done
  1657.  
  1658. sc_down:    mov ax,[W_Y1]           ;Window one line?
  1659.             mov bx,[W_Y2]
  1660.             cmp ax,bx
  1661.             jne sc_cont2
  1662.             jmp sc_tiny
  1663.  
  1664. sc_cont2:   inc ax
  1665.             dec bx
  1666.             push [W_X1] [W_Y1] [W_X2]
  1667.             push bx [W_X1] ax       ;Push args
  1668.             call movetext           ;Scroll down
  1669.  
  1670.             push [W_X1] [W_X2]      ;Clear top line
  1671.             push [W_Y1] ' '
  1672.             call hline
  1673.             jmp sc_done
  1674.  
  1675. sc_left:    mov ax,[W_X1]           ;Window one column?
  1676.             cmp ax,[W_X2]
  1677.             je sc_tiny
  1678.  
  1679.             inc ax
  1680.             push ax [W_Y1]          ;Push args
  1681.             push [W_X2] [W_Y2]
  1682.             push [W_X1] [W_Y1]
  1683.             call movetext           ;Scroll left
  1684.  
  1685.             push [W_Y1] [W_Y2]      ;Clear right column
  1686.             push [W_X2] ' '
  1687.             call vline
  1688.             jmp sc_done
  1689.  
  1690. sc_right:   mov ax,[W_X1]           ;Window one column?
  1691.             mov bx,[W_X2]
  1692.             cmp ax,bx
  1693.             je sc_tiny
  1694.  
  1695.             inc ax
  1696.             dec bx
  1697.             push [W_X1] [W_Y1] bx   ;Push args
  1698.             push [W_Y2] ax [W_Y1]
  1699.             call movetext           ;Scroll right
  1700.  
  1701.             push [W_Y1] [W_Y2]      ;Clear left column
  1702.             push [W_X1] ' '
  1703.             call vline
  1704.             jmp sc_done
  1705.  
  1706. sc_tiny:    call clrwin             ;Clear window
  1707.  
  1708. sc_done:    popa                    ;Restore registers
  1709.             pop bp                  ;Delete stack frame
  1710.             ret 2                   ;Return
  1711.  
  1712. ScTable     dw offset sc_up
  1713.             dw offset sc_down
  1714.             dw offset sc_left
  1715.             dw offset sc_right
  1716.  
  1717. EndP        scroll
  1718.  
  1719. End
  1720.  
  1721. ~~~C_DILINE
  1722. Ideal
  1723.  
  1724. Include     "textmac.inc"           ;Include macros
  1725. Include     "textdat.inc"           ;Include data
  1726.  
  1727. Extrn       movetext:near, hline:near, vline:near
  1728. Public      delline, insline
  1729.  
  1730. Model Tiny
  1731. P186
  1732. CodeSeg
  1733.  
  1734. ;****************** delline() -- Delete line from window
  1735. ;void delline(int y);
  1736.  
  1737. Proc        delline
  1738.  
  1739.             push bp                 ;Set up stack frame
  1740.             mov bp,sp
  1741.             pusha                   ;Save registers
  1742.  
  1743.             mov ax,[bp+4]
  1744.  
  1745.             cmp [W_Rel],0           ;Relativity check
  1746.             je dl_norel
  1747.  
  1748.             add ax,[W_Y1]           ;Adjust to window
  1749.  
  1750. dl_norel:   cmp ax,[W_Y1]           ;Clip to window
  1751.             jl dl_done
  1752.             cmp ax,[W_Y2]
  1753.             jg dl_done
  1754.             je dl_clear
  1755.  
  1756.             inc ax
  1757.             push [W_X1] ax [W_X2]   ;Push args
  1758.             dec ax
  1759.             push [W_Y2] [W_X1] ax
  1760.             call movetext           ;Scroll up
  1761.  
  1762. dl_clear:   push [W_X1] [W_X2]      ;Clear bottom line
  1763.             push [W_Y2] ' '
  1764.             call hline
  1765.  
  1766. dl_done:    popa                    ;Restore registers
  1767.             pop bp                  ;Delete stack frame
  1768.             ret 2                   ;Return
  1769.  
  1770. EndP        delline
  1771.  
  1772. ;****************** insline() -- Insert line in window
  1773. ;void insline(int y);
  1774.  
  1775. Proc        insline
  1776.  
  1777.             push bp                 ;Set up stack frame
  1778.             mov bp,sp
  1779.             pusha                   ;Save registers
  1780.  
  1781.             mov ax,[bp+4]
  1782.  
  1783.             cmp [W_Rel],0           ;Relativity check
  1784.             je il_norel
  1785.  
  1786.             add ax,[W_Y1]           ;Adjust to window
  1787.  
  1788. il_norel:   cmp ax,[W_Y1]           ;Clip to window
  1789.             jl il_done
  1790.             cmp ax,[W_Y2]
  1791.             jg il_done
  1792.             je il_clear
  1793.  
  1794.             mov bx,ax               ;BX = y - 1,
  1795.             mov cx,[W_Y2]           ;CX = W_Y2 - 1
  1796.             inc bx
  1797.             dec cx
  1798.             push [W_X1] ax [W_X2]   ;Push args
  1799.             push cx [W_X1] bx
  1800.             call movetext           ;Scroll down
  1801.  
  1802. il_clear:   push [W_X1] [W_X2]      ;Clear inserted line
  1803.             push ax ' '
  1804.             call hline
  1805.  
  1806. il_done:    popa                    ;Restore registers
  1807.             pop bp                  ;Delete stack frame
  1808.             ret 2                   ;Return
  1809.  
  1810. EndP        insline
  1811.  
  1812. End
  1813.  
  1814. ~~~C_TGETLN
  1815. Ideal
  1816.  
  1817. Include     "textmac.inc"           ;Include macros
  1818. Include     "textdat.inc"           ;Include data
  1819.  
  1820. Extrn       tputs:near,setctype:near,gety:near
  1821. Extrn       gotoxy:near,getx:near,getctype:near
  1822. Extrn       memset:near,hline:near
  1823. Public      getline,setglchar
  1824.  
  1825. Model Tiny
  1826. P186
  1827. CodeSeg
  1828.  
  1829. ;****************** setglchar() -- Set field fill char for getline()
  1830. ;void setglchar(int chr);
  1831.  
  1832. chr         equ bp+4
  1833.  
  1834. Proc        setglchar
  1835.  
  1836.             push bp                 ;Set up stack frame
  1837.             mov bp,sp
  1838.  
  1839.             push [chr]              ;Set gl_fillchar
  1840.             pop [gl_fillchar]
  1841.  
  1842.             pop bp                  ;Delete stack frame
  1843.             ret 2                   ;Return
  1844.  
  1845. EndP        setglchar
  1846.  
  1847. ;****************** getline() -- Get line of text, with edit
  1848. ;void getline(int x, int y, char *strp, int min, int max);
  1849.  
  1850. x           equ bp+12
  1851. y           equ bp+10
  1852. strp        equ bp+8
  1853. min         equ bp+6
  1854. max         equ bp+4
  1855.  
  1856. Proc        getline
  1857.  
  1858.             push bp                 ;Set up stack frame
  1859.             mov bp,sp
  1860.             pusha                   ;Save registers
  1861.  
  1862.             call getctype           ;Save cursor type
  1863.             mov [gl_buf],ax
  1864.             call getx               ;Save cursor position
  1865.             mov [gl_buf+2],ax
  1866.             call gety
  1867.             mov [gl_buf+4],ax
  1868.  
  1869.             mov [gl_iflag],1        ;Insert initially on
  1870.  
  1871.             mov bx,[strp]           ;Clear the string buffer
  1872.             mov si,[max]
  1873.             push bx si 0
  1874.             call memset
  1875.  
  1876.             mov di,si               ;DI = maximum length
  1877.             xor si,si               ;String pos = 0
  1878.             dec di
  1879.             dec di
  1880.             mov cx,1                ;Set modify flag
  1881.  
  1882. gl_loop:    call gl_redraw          ;Redraw entry field
  1883.  
  1884. gl_kloop:   xor ax,ax               ;Get a key
  1885.             int 16h
  1886.             cmp al,0Dh              ;Enter?
  1887.             je gl_enter
  1888.             cmp al,1Bh              ;Escape?
  1889.             je gl_esc
  1890.             cmp al,08h              ;Backspace?
  1891.             je gl_bksp
  1892.             test al,al              ;Alphanumeric char?
  1893.             jne gl_char
  1894.             cmp ah,4Bh              ;Left?
  1895.             je gl_left
  1896.             cmp ah,4Dh              ;Right?
  1897.             je gl_right
  1898.             cmp ah,47h              ;Home?
  1899.             je gl_home
  1900.             cmp ah,4Fh              ;End?
  1901.             je gl_end
  1902.             cmp ah,52h              ;Insert?
  1903.             jne gl_skip0
  1904.             jmp gl_insert
  1905. gl_skip0:   cmp ah,53h              ;Delete?
  1906.             jne gl_kloop            ;Invalid, loop
  1907.             jmp gl_delete
  1908.  
  1909. ;****************** Key Processing Loops
  1910.  
  1911. gl_char:    mov dl,al               ;DL = char
  1912.             mov ax,[gl_iflag]       ;Check insert flag
  1913.             test ax,ax
  1914.             jz gl_skip1
  1915.  
  1916.             push di                 ;Save DI
  1917. gl_sloop1:  mov al,[bx+di-1]        ;Shift string right
  1918.             mov [bx+di],al
  1919.             dec di
  1920.             cmp di,si
  1921.             ja gl_sloop1
  1922.             pop di                  ;Restore DI
  1923.  
  1924. gl_skip1:   inc cx                  ;Set modify flag
  1925.             mov [bx+si],dl          ;Store char
  1926.             cmp si,di               ;Already at right?
  1927.             je gl_loop
  1928.             inc si                  ;Move right
  1929.             jmp gl_loop             ;Loop back
  1930.  
  1931. gl_enter:   push si
  1932.             mov si,di               ;SI = maximum+1
  1933.             inc si
  1934.  
  1935. gl_sloop0:  test si,si              ;Hit the left?
  1936.             jz gl_cont
  1937.             cmp [byte bx+si-1],0    ;End of string?
  1938.             jne gl_cont
  1939.             dec si                  ;Move left
  1940.             jmp gl_sloop0           ;Loop back
  1941. gl_cont:    mov dx,si               ;DX = end point
  1942.             pop si                  ;Restore SI
  1943.  
  1944.             cmp dx,[min]            ;Below minimum, ignore
  1945.             jae gl_finish           ;Otherwise, quit
  1946. gl_jmpk:    jmp gl_kloop
  1947.  
  1948. gl_esc:     push bx di 0            ;Clear buffer...
  1949.             call memset
  1950.             xor si,si
  1951.             call gl_redraw
  1952.             jmp gl_done
  1953.  
  1954. gl_bksp:    test si,si              ;Can't backspace from
  1955.             jz gl_jmpk              ;the first char
  1956.             dec si                  ;Delete at SI-1
  1957.             jmp gl_delete
  1958.  
  1959. gl_left:    test si,si              ;Already at left?
  1960.             jz gl_jmpk
  1961.             dec si                  ;Move left
  1962.             jmp gl_loop             ;Loop back
  1963.  
  1964. gl_right:   cmp si,di               ;Already at right?
  1965.             jae gl_jmpk
  1966.             inc si                  ;Move right
  1967.             jmp gl_loop             ;Loop back
  1968.  
  1969. gl_home:    xor si,si               ;Move to left
  1970. gl_jmp:     jmp gl_loop             ;Loop back
  1971.  
  1972. gl_end:     mov si,di               ;SI = maximum
  1973.             cmp [byte bx+si],0      ;Buffer full, move to end
  1974.             jne gl_jmp
  1975.  
  1976. gl_sloop2:  test si,si              ;Hit the left?
  1977.             jz gl_jmp
  1978.             cmp [byte bx+si-1],0    ;End of string?
  1979.             jne gl_jmp
  1980.             dec si                  ;Move left
  1981.             jmp gl_sloop2           ;Loop back
  1982.  
  1983. gl_insert:  mov ax,1                ;Toggle insert flag
  1984.             sub ax,[gl_iflag]
  1985.             mov [gl_iflag],ax
  1986.             jmp gl_loop             ;Loop back
  1987.  
  1988. gl_delete:  push si                 ;Save SI
  1989.             inc si
  1990. gl_sloop3:  mov ax,[bx+si]          ;Shift string left
  1991.             mov [bx+si-1],al
  1992.             inc si
  1993.             cmp si,di
  1994.             jbe gl_sloop3
  1995.             pop si                  ;Restore SI
  1996.             mov [byte bx+di],0      ;End with space
  1997.             inc cx                  ;Set modify flag
  1998.             jmp gl_loop             ;Loop back
  1999.  
  2000. ;****************** End of Key Processing
  2001.  
  2002. gl_finish:  mov si,dx               ;SI = length
  2003.             mov [byte bx+si],0      ;Terminate with a null
  2004.  
  2005. gl_done:    push [gl_buf+2]         ;Restore cursor position
  2006.             push [gl_buf+4]
  2007.             call gotoxy
  2008.             push [gl_buf]           ;Restore cursor type
  2009.             call setctype
  2010.  
  2011.             popa                    ;Restore registers
  2012.             pop bp                  ;Delete stack frame
  2013.             ret 10                  ;Return
  2014.  
  2015. gl_redraw:  pusha                   ;Save all registers
  2016.             test cx,cx              ;Check modify flag
  2017.             jz gl_setcur
  2018.             mov cx,[x]              ;Set up to clear the field
  2019.             push cx
  2020.             add cx,di               ;Clear the field
  2021.             push cx [y] [gl_fillchar]
  2022.             call hline
  2023.             push [x] [y] bx         ;Show the string
  2024.             call tputs
  2025.  
  2026. gl_setcur:  mov ax,[x]              ;Set the cursor position
  2027.             add ax,si
  2028.             push ax [y]
  2029.             call gotoxy
  2030.  
  2031.             mov bx,[gl_iflag]       ;AX = cursor to use
  2032.             add bx,bx
  2033.             mov ax,[gl_curs+bx]
  2034.             push ax                 ;Set cursor type
  2035.             call setctype
  2036.  
  2037.             popa                    ;Restore registers
  2038.             xor cx,cx               ;Reset modify flag
  2039.             ret                     ;Return
  2040.  
  2041. gl_buf      dw 3 dup(0)             ;Scratch buffer
  2042. gl_iflag    dw 0                    ;Insert flag
  2043.  
  2044. gl_curs     dw 000Dh,0C0Dh          ;Cursors
  2045. gl_fillchar dw 0020h                ;Fill char (space)
  2046.  
  2047. EndP        getline
  2048.  
  2049. End
  2050.  
  2051. ~~~C_AMOUSE
  2052. Ideal
  2053.  
  2054. Public      minit, mclose, mshow, mhide
  2055. Public      mget, mgetdn, mgetup
  2056.  
  2057. Model Tiny
  2058. P186
  2059. CodeSeg
  2060.  
  2061. ;****************** Mouse Data
  2062.  
  2063. M_X         dw 0                    ;Mouse X
  2064. M_Y         dw 0                    ;Mouse Y
  2065.  
  2066. ScrnBuf     dw 0                    ;Screen buffer
  2067.  
  2068. MouseFound  dw 0                    ;Existence flag
  2069. MouseOn     dw 0                    ;Display flag
  2070.  
  2071. ;****************** INTERNAL PROC MouseHandler
  2072.  
  2073. Proc        MouseHandler
  2074.  
  2075.             cmp [cs:MouseOn],0      ;Cursor off, skip
  2076.             je MH_Skip
  2077.             call PutCursor          ;Toggle cursor off
  2078.             mov [cs:M_X],cx         ;Set X, Y
  2079.             mov [cs:M_Y],dx
  2080.             call PutCursor          ;Toggle cursor on
  2081. MH_Skip:    retf                    ;Return
  2082.  
  2083. EndP        MouseHandler
  2084.  
  2085. ;****************** INTERNAL PROC PutCursor
  2086.  
  2087. Proc        PutCursor
  2088.  
  2089.             pusha                   ;Save all registers
  2090.             push ds
  2091.  
  2092.             push 0A000h             ;DS = video memory
  2093.             pop ds
  2094.  
  2095.             mov bx,[cs:M_Y]         ;AX, BX = X, Y
  2096.             mov ax,[cs:M_X]
  2097.             shl bx,5                ;BX = offset
  2098.             shr ax,2
  2099.             add bx,ax
  2100.  
  2101.             xor [byte bx+1],77h     ;Toggle cursor
  2102.  
  2103.             pop ds                  ;Restore registers
  2104.             popa
  2105.             ret                     ;Return
  2106.  
  2107. EndP        PutCursor
  2108.  
  2109. ;****************** minit() -- Initialize mouse system
  2110. ;int minit(void);
  2111.  
  2112. Proc        minit
  2113.  
  2114.             pusha                   ;Save all registers
  2115.  
  2116.             mov ax,21h              ;Initialize mouse driver
  2117.             int 33h
  2118.             test ax,ax
  2119.             jz im_nomouse
  2120.  
  2121.             mov ax,7                ;Set X limits
  2122.             xor cx,cx               ;(90 * 8) - 1
  2123.             mov dx,719
  2124.             int 33h
  2125.  
  2126.             mov ax,8                ;Set Y limits
  2127.             xor cx,cx               ;(34 * 8) - 1
  2128.             mov dx,271
  2129.             int 33h
  2130.  
  2131.             mov ax,4                ;Set position to (0, 0)
  2132.             xor cx,cx
  2133.             xor dx,dx
  2134.             int 33h
  2135.  
  2136.             mov [M_X],cx            ;Save position
  2137.             mov [M_Y],dx
  2138.  
  2139.             push es                 ;Save ES
  2140.  
  2141.             push cs                 ;ES:DX = mouse handler
  2142.             pop es
  2143.             mov dx,offset MouseHandler
  2144.             mov ax,0Ch              ;Set handler
  2145.             mov cx,1                ;for motion
  2146.             int 33h
  2147.  
  2148.             mov [MouseOn],0         ;Mouse is off
  2149.  
  2150.             pop es                  ;Restore ES
  2151.  
  2152.             mov [MouseFound],1      ;Set mouse flag
  2153.             popa                    ;Restore registers
  2154.             mov ax,1                ;Return 1
  2155.             ret
  2156.  
  2157. im_nomouse: mov [MouseFound],0      ;Reset mouse flag
  2158.             popa                    ;Restore registers
  2159.             xor ax,ax               ;Return 0
  2160.             ret
  2161.  
  2162. EndP        minit
  2163.  
  2164. ;****************** mclose() -- End mouse system
  2165. ;void mclose(void);
  2166.  
  2167. Proc        mclose
  2168.  
  2169.             mov [MouseFound],0      ;Reset mouse flag
  2170.  
  2171.             cmp [MouseOn],0         ;Mouse off, skip
  2172.             je em_Off
  2173.             mov [MouseOn],0         ;Reset cursor flag
  2174.             call PutCursor          ;Hide mouse cursor
  2175.  
  2176. em_Off:     push ax                 ;Save AX
  2177.             mov ax,21h              ;Reinitialize mouse driver
  2178.             int 33h
  2179.             pop ax                  ;Restore AX
  2180.             ret                     ;Return
  2181.  
  2182. EndP        mclose
  2183.  
  2184. ;****************** mshow() -- Show mouse cursor
  2185. ;void mshow(void);
  2186.  
  2187. Proc        mshow
  2188.  
  2189.             cmp [MouseOn],1         ;Already on, do nothing
  2190.             je sm_done
  2191.             call PutCursor          ;Show mouse cursor
  2192.             mov [MouseOn],1         ;Set cursor flag
  2193. sm_done:    ret                     ;Return
  2194.  
  2195. EndP        mshow
  2196.  
  2197. ;****************** mhide() -- Hide mouse cursor
  2198. ;void mhide(void);
  2199.  
  2200. Proc        mhide
  2201.  
  2202.             cmp [MouseOn],0         ;Already off, do nothing
  2203.             je hm_done
  2204.             mov [MouseOn],0         ;Reset cursor flag
  2205.             call PutCursor          ;Hide mouse cursor
  2206. hm_done:    ret                     ;Return
  2207.  
  2208. EndP        mhide
  2209.  
  2210. ;****************** mget() -- Get mouse position - returns AX,BX,CX
  2211. ;(int, int, int) mget(void);
  2212.  
  2213. Proc        mget
  2214.  
  2215.             push dx                 ;Save registers
  2216.  
  2217.             mov ax,3                ;Get mouse position
  2218.             int 33h
  2219.  
  2220.             shr cx,3                ;Fix values
  2221.             shr dx,3
  2222.  
  2223.             xchg ax,dx              ;Return AX = button state,
  2224.             xchg ax,cx              ;       BX = X value, and
  2225.             xchg ax,bx              ;       CX = Y value
  2226.  
  2227.             pop dx                  ;Restore registers
  2228.             ret                     ;Return
  2229.  
  2230. EndP        mget
  2231.  
  2232. ;****************** mgetdn() -- Get mouse press info - returns AX,BX,CX
  2233. ;(int, int, int) mgetdn(int btn);
  2234.  
  2235. Proc        mgetdn
  2236.  
  2237.             push bp                 ;Set up stack frame
  2238.             mov bp,sp
  2239.             push dx                 ;Save registers
  2240.  
  2241.             mov ax,5                ;Get mouse press info
  2242.             mov bx,[bp+4]
  2243.             int 33h
  2244.  
  2245.             shr cx,3                ;Fix values
  2246.             shr dx,3
  2247.  
  2248.             xchg ax,dx              ;Return AX = press count,
  2249.             xchg ax,cx              ;       BX = X value, and
  2250.             xchg ax,bx              ;       CX = Y value
  2251.  
  2252.             pop dx                  ;Restore registers
  2253.             pop bp                  ;Delete stack frame
  2254.             ret 2                   ;Return
  2255.  
  2256. EndP        mgetdn
  2257.  
  2258. ;****************** mgetup() -- Get mouse release info - returns AX,BX,CX
  2259. ;(int, int, int) mgetup(int btn);
  2260.  
  2261. Proc        mgetup
  2262.  
  2263.             push bp                 ;Set up stack frame
  2264.             mov bp,sp
  2265.             push dx                 ;Save registers
  2266.  
  2267.             mov ax,6                ;Get mouse release info
  2268.             mov bx,[bp+4]
  2269.             int 33h
  2270.  
  2271.             shr cx,3                ;Fix values
  2272.             shr dx,3
  2273.  
  2274.             xchg ax,dx              ;Return AX = release count,
  2275.             xchg ax,cx              ;       BX = X value, and
  2276.             xchg ax,bx              ;       CX = Y value
  2277.  
  2278.             pop dx                  ;Restore registers
  2279.             pop bp                  ;Delete stack frame
  2280.             ret 2                   ;Return
  2281.  
  2282. EndP        mgetup
  2283.  
  2284. End
  2285.  
  2286. ; Graphics code by Tylisha C. Andersen.  I don't know how it
  2287. ; works, that's why I haven't added better comments.
  2288.  
  2289. ~~~C_GRAPH1
  2290. Ideal
  2291. Jumps
  2292.  
  2293. Public      initgraph, closegraph, putpix, getpix
  2294. Public      setgcolor, getgcolor, putrow
  2295. Public      cls, setgwin, GMode, GColor
  2296.  
  2297. Model Tiny
  2298. P186
  2299. CodeSeg
  2300.  
  2301. ;****************** Data Section
  2302.  
  2303. GW_X1       dw    0                 ; window parameters
  2304. GW_Y1       dw    0
  2305. GW_X2       dw    0
  2306. GW_Y2       dw    0
  2307.  
  2308. GMode       db    0                 ; video mode
  2309. GColor      db    0                 ; drawing color
  2310.  
  2311. ;****************** Code Section
  2312.  
  2313. ;****************** initgraph() -- Initialize graphics system
  2314. ;void initgraph(int mode);         0 = 320x200x256
  2315. ;                                  1 = 640x480x16
  2316. ;                                  2 = 320x400x256
  2317.  
  2318. Proc        initgraph
  2319.  
  2320.             push  bp                ; pascal stack frame
  2321.             mov   bp, sp
  2322.             pusha
  2323.  
  2324.             mov   ax, 13h           ; set video mode
  2325.             mov   bl, [bp+4]
  2326.             and   bl, 3
  2327.             mov   [GMode], bl
  2328.             mov   dh, bl
  2329.             and   dh, 1
  2330.             sub   al, dh
  2331.             int   10h
  2332.  
  2333.             mov   cx, 319           ; assume lo-res
  2334.             mov   dx, 199
  2335.  
  2336.             test  bl, 2             ; check video mode
  2337.             jnz   a_1
  2338.             test  bl, bl
  2339.             jz    a_2
  2340.  
  2341.             mov   dx, 03CEh         ; set write mode
  2342.             mov   ax, 0305h
  2343.             out   dx, ax
  2344.             mov   cx, 639           ; set screen size
  2345.             mov   dx, 479
  2346.             jmp   a_2
  2347.  
  2348. a_1:        mov   dx, 03C4h         ; set dechain mode
  2349.             mov   ax, 0604h         ; for 320x400x256
  2350.             out   dx, ax
  2351.             mov   dx, 03D4h
  2352.             mov   ax, 0E317h
  2353.             out   dx, ax
  2354.             mov   ax, 0014h
  2355.             out   dx, ax
  2356.             mov   ax, 4009h
  2357.             out   dx, ax
  2358.             mov   dx, 399           ; set screen size
  2359.  
  2360. a_2:        xor   ax, ax            ; initialize variables
  2361.             mov   [GColor], 0Fh
  2362.             mov   [GW_X1], ax
  2363.             mov   [GW_Y1], ax
  2364.             mov   [GW_X2], cx
  2365.             mov   [GW_Y2], dx
  2366.  
  2367.             call  cls               ; set color white
  2368.  
  2369.             popa                    ; return code
  2370.             pop   bp
  2371.             ret   2
  2372.  
  2373. EndP        initgraph
  2374.  
  2375. ;****************** closegraph() -- Close graphics system
  2376. ;void closegraph(void);
  2377.  
  2378. Proc        closegraph
  2379.  
  2380.             push  ax                ; set normal video mode
  2381.             mov   ax, 03h
  2382.             int   10h
  2383.             pop   ax
  2384.             ret
  2385.  
  2386. EndP        closegraph
  2387.  
  2388. ;****************** putpix() -- Put a pixel
  2389. ;void putpix(int x, int y);
  2390.  
  2391. Proc        putpix
  2392.  
  2393.             push  bp                ; pascal stack frame
  2394.             mov   bp, sp
  2395.             push  es
  2396.             pusha
  2397.  
  2398.             mov   ax, [bp+6]        ; get position
  2399.             mov   bx, [bp+4]
  2400.  
  2401.             cmp   ax, [GW_X1]       ; clip pixel
  2402.             jl    b_3
  2403.             cmp   ax, [GW_X2]
  2404.             jg    b_3
  2405.             cmp   bx, [GW_Y1]
  2406.             jl    b_3
  2407.             cmp   bx, [GW_Y2]
  2408.             jg    b_3
  2409.  
  2410.             push  0A000h            ; set video memory
  2411.             pop   es
  2412.  
  2413.             cmp   [GMode], 1        ; check video mode
  2414.             ja    b_2
  2415.             je    b_1
  2416.  
  2417.             add   ah, bl            ; put pixel: lo-res
  2418.             shl   bx, 6
  2419.             add   bx, ax
  2420.             mov   al, [GColor]
  2421.             mov   [es:bx], al
  2422.             jmp   b_3
  2423.  
  2424. b_1:        mov   cx, bx            ; put pixel: hi-res
  2425.             shl   bx, 2
  2426.             add   bx, cx
  2427.             shl   bx, 4
  2428.             mov   cx, ax
  2429.             shr   ax, 3
  2430.             add   bx, ax
  2431.             mov   al, 80h
  2432.             ror   al, cl
  2433.             xchg  [es:bx], al
  2434.             jmp   b_3
  2435.  
  2436. b_2:        mov   cx, ax            ; put pixel: med-res
  2437.             shl   bx, 4
  2438.             mov   ax, bx
  2439.             shl   bx, 2
  2440.             add   bx, ax
  2441.             mov   ax, cx
  2442.             shr   ax, 2
  2443.             add   bx, ax
  2444.             and   cl, 3
  2445.             mov   dx, 03C4h         ; set plane
  2446.             mov   ax, 0102h
  2447.             shl   ah, cl
  2448.             out   dx, ax
  2449.             mov   al, [GColor]
  2450.             mov   [es:bx], al
  2451.  
  2452. b_3:        popa                    ; return code
  2453.             pop   es bp
  2454.             ret   4
  2455.  
  2456. EndP        putpix
  2457.  
  2458. ;****************** getpix() -- Read a pixel
  2459. ;int getpix(int x, int y);
  2460.  
  2461. Proc        getpix
  2462.  
  2463.             push  bp                ; pascal stack frame
  2464.             mov   bp, sp
  2465.             push  es
  2466.             pusha
  2467.  
  2468.             mov   ax, [bp+6]        ; get position
  2469.             mov   bx, [bp+4]
  2470.  
  2471.             push  0A000h            ; set video memory
  2472.             pop   es
  2473.  
  2474.             cmp   [GMode], 1        ; check video mode
  2475.             ja    c_3
  2476.             je    c_1
  2477.  
  2478.             add   ah, bl            ; get pixel: lo-res
  2479.             shl   bx, 6
  2480.             add   bx, ax
  2481.             mov   al, [es:bx]
  2482.             jmp   c_4
  2483.  
  2484. c_1:        mov   cx, bx            ; get pixel: hi-res
  2485.             shl   bx, 2             ; figure out the offset
  2486.             add   bx, cx
  2487.             shl   bx, 4
  2488.             mov   cx, ax
  2489.             shr   ax, 3
  2490.             add   bx, ax
  2491.             mov   si, bx
  2492.             xor   bh, bh
  2493.  
  2494.             mov   dx, 03CEh         ; set up port
  2495.             mov   ax, 0304h
  2496.  
  2497. c_2:        out   dx, ax            ; set plane
  2498.             mov   bl, [es:si]       ; read bit
  2499.             or    bl, [es:si]
  2500.             rol   bl, cl
  2501.             shl   bx, 1
  2502.             dec   ah                ; loop
  2503.             jnl   c_2
  2504.  
  2505.             mov   al, bh            ; al = color
  2506.             jmp   c_4
  2507.  
  2508. c_3:        mov   cx, ax            ; get pixel: med-res
  2509.             shl   bx, 4
  2510.             mov   ax, bx
  2511.             shl   bx, 2
  2512.             add   bx, ax
  2513.             mov   ax, cx
  2514.             shr   ax, 2
  2515.             add   bx, ax
  2516.             and   cl, 3
  2517.             mov   dx, 03CEh         ; set plane
  2518.             mov   al, 4
  2519.             mov   ah, cl
  2520.             out   dx, ax
  2521.             mov   al, [es:bx]
  2522.  
  2523. c_4:        xor   ah, ah
  2524.             mov   es, ax            ; ax = result
  2525.             popa
  2526.             mov   ax, es
  2527.             pop   es bp             ; return code
  2528.             ret   4
  2529.  
  2530. EndP        getpix
  2531.  
  2532. ;****************** setgwin() -- Set graphics window
  2533. ;void setgwin(int x1, int y1, int x2, int y2);
  2534.  
  2535. Proc        setgwin
  2536.  
  2537.             push  bp                ; pascal stack frame
  2538.             mov   bp, sp
  2539.             push  ax
  2540.  
  2541.             mov   ax, [bp+10]       ; set window variables
  2542.             mov   [GW_X1], ax
  2543.             mov   ax, [bp+8]
  2544.             mov   [GW_Y1], ax
  2545.             mov   ax, [bp+6]
  2546.             mov   [GW_X2], ax
  2547.             mov   ax, [bp+4]
  2548.             mov   [GW_Y2], ax
  2549.  
  2550.             pop   ax bp             ; return code
  2551.             ret   8
  2552.  
  2553. EndP        setgwin
  2554.  
  2555. ;****************** putrow() -- Put a row of pixels
  2556. ;void putrow(int x1, int x2, int y);
  2557.  
  2558. Proc        putrow
  2559.  
  2560.             push  bp                ; pascal stack frame
  2561.             mov   bp, sp
  2562.             push  es
  2563.             pusha
  2564.  
  2565.             mov   ax, [bp+8]        ; get position
  2566.             mov   bx, [bp+4]
  2567.             mov   cx, [bp+6]
  2568.  
  2569.             cmp   ax, cx            ; left to right
  2570.             jng   $+3
  2571.             xchg  ax, cx
  2572.  
  2573.             cmp   ax, [GW_X2]       ; clip the line
  2574.             jg    d_7
  2575.             cmp   cx, [GW_X1]
  2576.             jl    d_7
  2577.             cmp   bx, [GW_Y2]
  2578.             jg    d_7
  2579.             cmp   bx, [GW_Y1]
  2580.             jl    d_7
  2581.             cmp   ax, [GW_X1]
  2582.             jnl   d_1
  2583.             mov   ax, [GW_X1]
  2584. d_1:        cmp   cx, [GW_X2]
  2585.             jng   d_2
  2586.             mov   cx, [GW_X2]
  2587.  
  2588. d_2:        mov   [bp+8], ax        ; save position
  2589.             mov   [bp+4], bx
  2590.             mov   [bp+6], cx
  2591.  
  2592.             push  0A000h            ; set video memory
  2593.             pop   es
  2594.  
  2595.             cmp   [GMode], 1        ; check video mode
  2596.             ja    d_8
  2597.             je    d_3
  2598.  
  2599.             sub   cx, ax            ; put row: lo-res
  2600.             add   ah, bl
  2601.             shl   bx, 6
  2602.             add   bx, ax
  2603.             mov   di, bx
  2604.             inc   cx
  2605.             mov   al, [GColor]
  2606.             rep   stosb
  2607.             jmp   d_7
  2608.  
  2609. d_3:        mov   dx, cx            ; put row: hi-res
  2610.             sub   dx, ax            ; figure out offset
  2611.             imul  bx, 80
  2612.             mov   cx, ax
  2613.             shr   ax, 3
  2614.             add   bx, ax
  2615.             mov   al, 80h
  2616.             ror   al, cl
  2617.             mov   ah, al
  2618.             mov   cx, dx
  2619.             jcxz  d_6
  2620.  
  2621. d_4:        shr   ah, 1             ; shift right
  2622.             jnz   d_5
  2623.             mov   ah, [es:bx]       ; put pixels
  2624.             mov   [es:bx], al
  2625.             inc   bx                ; next byte
  2626.             mov   ah, 80h           ; reset
  2627.             xor   al, al
  2628.  
  2629. d_5:        or    al, ah            ; add in pixel
  2630.             loop  d_4               ; loop
  2631.  
  2632. d_6:        mov   ah, [es:bx]       ; put last pixels
  2633.             mov   [es:bx], al
  2634.  
  2635. d_7:        popa                    ; return code
  2636.             pop   es bp
  2637.             ret   6
  2638.  
  2639. d_8:        test  ax, 3             ; put row: med-res
  2640.             jz    d_9               ; put first pixels
  2641.             push  ax bx
  2642.             call  putpix
  2643.             inc   ax
  2644.             cmp   ax, cx
  2645.             jle   d_8
  2646.  
  2647. d_9:        push  cx bx             ; put last pixels
  2648.             call  putpix
  2649.             cmp   cx, ax
  2650.             jle   d_7
  2651.             test  cx, 3
  2652.             loopnz  d_9
  2653.  
  2654. d_10:       imul  di, bx, 80        ; figure out offset, length
  2655.             shr   ax, 2
  2656.             add   di, ax
  2657.             shr   cx, 2
  2658.             sub   cx, ax
  2659.             jl    d_7
  2660.             inc   cx
  2661.  
  2662.             mov   dx, 03C4h         ; set all planes
  2663.             mov   ax, 0F02h
  2664.             out   dx, ax
  2665.             mov   al, [GColor]      ; draw middle
  2666.             rep   stosb
  2667.             jmp   d_7
  2668.  
  2669. EndP        putrow
  2670.  
  2671. ;****************** setgcolor() -- Set graphics color
  2672. ;void setgcolor(int color);
  2673.  
  2674. Proc        setgcolor
  2675.  
  2676.             push  bp                ; pascal stack frame
  2677.             mov   bp, sp
  2678.             pusha
  2679.  
  2680.             mov   ah, [bp+4]        ; set color variable
  2681.             mov   [GColor], ah
  2682.             cmp   [GMode], 1        ; check video mode
  2683.             jne    e_1
  2684.  
  2685.             xor   al, al            ; set hardware color
  2686.             mov   dx, 03CEh
  2687.             out   dx, ax
  2688.  
  2689. e_1:        popa                    ; return code
  2690.             pop   bp
  2691.             ret   2
  2692.  
  2693. EndP        setgcolor
  2694.  
  2695. ;****************** getgcolor() -- Return graphics color
  2696. ;int getgcolor(void);
  2697.  
  2698. Proc        getgcolor
  2699.  
  2700.             mov   al, [GColor]      ; get color
  2701.             xor   ah, ah
  2702.             ret                     ; return
  2703.  
  2704. EndP        getgcolor
  2705.  
  2706. ;****************** cls() -- Clear screen
  2707. ;void cls(void);
  2708.  
  2709. Proc        cls
  2710.  
  2711.             push  es                ; save regs
  2712.             pusha
  2713.  
  2714.             mov   bl, [GColor]      ; save color
  2715.  
  2716.             push  0A000h            ; set video memory
  2717.             pop   es
  2718.  
  2719.             cmp   [GMode], 1        ; check video mode
  2720.             ja    f_3
  2721.             je    f_1
  2722.  
  2723.             xor   ax, ax            ; cls setup: lo-res
  2724.             mov   cx, 32000
  2725.             jmp   f_2
  2726.  
  2727. f_1:        mov   ax, -1            ; cls setup: hi-res
  2728.             mov   cx, 19200
  2729.             push  0
  2730.             call  setgcolor
  2731.  
  2732. f_2:        xor   di, di            ; clear the screen
  2733.             rep   stosw
  2734.  
  2735.             push  bx                ; restore color
  2736.             call  setgcolor
  2737.  
  2738.             popa                    ; return code
  2739.             pop   es
  2740.             ret
  2741.  
  2742. f_3:        mov   dx, 03C4h         ; cls setup: med-res
  2743.             mov   ax, 0F02h
  2744.             out   dx, ax
  2745.             mov   cx, 16000
  2746.             xor   ax, ax
  2747.             jmp   f_2
  2748.  
  2749. EndP        cls
  2750.  
  2751. End
  2752.  
  2753. ~~~C_GRAPH2
  2754. Ideal
  2755. Jumps
  2756.  
  2757. Extrn       putpix:near, getpix:near
  2758. Extrn       putrow:near, setgcolor:near
  2759. Extrn       getgcolor:near, GMode:byte
  2760. Public      line, rect, frect, clrgwin
  2761. Public      outstr, getimage, putimage
  2762.  
  2763. Model Tiny
  2764. P186
  2765. CodeSeg
  2766.  
  2767. ;****************** line() -- Draw a straight line
  2768. ;void line(int x1, int y1, int x2, int y2);
  2769.  
  2770. Proc        line
  2771.  
  2772.             enter 4, 0              ; pascal stack frame
  2773.             pusha                   ; with local vars
  2774.  
  2775.             mov   ax, [bp+10]       ; get coordinates
  2776.             mov   bx, [bp+8]
  2777.             mov   cx, [bp+6]
  2778.             mov   dx, [bp+4]
  2779.  
  2780.             mov   si, cx            ; get x, y distance
  2781.             sub   si, ax
  2782.             jge   $+4
  2783.             neg   si
  2784.             mov   di, dx
  2785.             sub   di, bx
  2786.             jge   $+4
  2787.             neg   di
  2788.  
  2789.             mov   [bp-2], si        ; jump to x or y loop
  2790.             mov   [bp-4], di
  2791.             cmp   si, di
  2792.             jle   a_4
  2793.  
  2794.             cmp   ax, cx            ; go in the x direction
  2795.             jle   a_1
  2796.             xchg  ax, cx
  2797.             xchg  bx, dx
  2798.  
  2799. a_1:        xchg  ax, dx            ; get distance (cx)
  2800.             sub   cx, dx
  2801.             inc   cx
  2802.             sub   ax, bx            ; get y increment (ax)
  2803.             sar   ax, 16
  2804.             add   ax, ax
  2805.             inc   ax
  2806.             shr   si, 1             ; setup error term (si)
  2807.             sub   di, si
  2808.             mov   si, di
  2809.  
  2810. a_2:        push  dx bx             ; put pixel
  2811.             call  putpix
  2812.             test  si, si            ; check for y move
  2813.             jl    a_3
  2814.  
  2815.             add   bx, ax            ; move in y direction
  2816.             sub   si, [bp-2]
  2817.  
  2818. a_3:        inc   dx                ; move in x direction
  2819.             add   si, [bp-4]
  2820.             loop  a_2               ; loop
  2821.             jmp   a_8
  2822.  
  2823. a_4:        cmp   bx, dx            ; go in the y direction
  2824.             jle   a_5
  2825.             xchg  ax, cx
  2826.             xchg  bx, dx
  2827.  
  2828. a_5:        xchg  ax, cx            ; get distance (cx)
  2829.             sub   dx, bx
  2830.             xchg  cx, dx
  2831.             inc   cx
  2832.             sub   ax, dx            ; get x increment (ax)
  2833.             sar   ax, 16
  2834.             add   ax, ax
  2835.             inc   ax
  2836.             shr   di, 1             ; setup error term (si)
  2837.             sub   si, di
  2838.  
  2839. a_6:        push  dx bx             ; put pixel
  2840.             call  putpix
  2841.             test  si, si            ; check for x move
  2842.             jl    a_7
  2843.  
  2844.             add   dx, ax            ; move in x direction
  2845.             sub   si, [bp-4]
  2846.  
  2847. a_7:        inc   bx                ; move in y direction
  2848.             add   si, [bp-2]
  2849.             loop  a_6               ; loop
  2850.  
  2851. a_8:        popa                    ; return code
  2852.             leave
  2853.             ret   8
  2854.  
  2855. EndP        line
  2856.  
  2857. ;****************** rect() -- Draw a rectangle
  2858. ;void rect(int x1, int y1, int x2, int y2);
  2859.  
  2860. Proc        rect
  2861.  
  2862.             push  bp                ; pascal stack frame
  2863.             mov   bp, sp
  2864.             pusha
  2865.  
  2866.             mov   ax, [bp+10]       ; get coordinates
  2867.             mov   bx, [bp+8]
  2868.             mov   cx, [bp+6]
  2869.             mov   dx, [bp+4]
  2870.  
  2871.             push  ax cx bx          ; draw top edge
  2872.             call  putrow
  2873.             push  ax cx dx          ; draw bottom edge
  2874.             call  putrow
  2875.             push  ax bx ax dx       ; draw left edge
  2876.             call  line
  2877.             push  cx bx cx dx       ; draw right edge
  2878.             call  line
  2879.  
  2880.             popa                    ; return code
  2881.             pop   bp
  2882.             ret   8
  2883.  
  2884. EndP        rect
  2885.  
  2886. ;****************** frect() -- Draw a filled rectangle
  2887. ;void frect(int x1, int y1, int x2, int y2);
  2888.  
  2889. Proc        frect
  2890.  
  2891.             push  bp                ; pascal stack frame
  2892.             mov   bp, sp
  2893.             pusha
  2894.  
  2895.             mov   ax, [bp+10]       ; get coordinates
  2896.             mov   bx, [bp+8]
  2897.             mov   cx, [bp+6]
  2898.             mov   dx, [bp+4]
  2899.  
  2900.             cmp   bx, dx            ; top to bottom
  2901.             jle   $+4
  2902.             xchg  bx, dx
  2903.  
  2904. b_1:        push  ax cx bx          ; draw one row
  2905.             call  putrow
  2906.             inc   bx
  2907.             cmp   bx, dx            ; loop
  2908.             jle   b_1
  2909.  
  2910.             popa                    ; return code
  2911.             pop   bp
  2912.             ret   8
  2913.  
  2914. EndP        frect
  2915.  
  2916. ;****************** clrgwin() -- Clear the graphics window
  2917. ;void clrgwin(void);
  2918.  
  2919. Proc        clrgwin
  2920.  
  2921.             push  ax
  2922.             mov   ax, 199           ; get screen height (ax)
  2923.             cmp   [GMode], 0
  2924.             je    c_1
  2925.             mov   ax, 479
  2926.  
  2927. c_1:        push  0 639 ax          ; clear one line
  2928.             call  putrow
  2929.             dec   ax                ; loop
  2930.             jns   c_1
  2931.             pop   ax                ; return
  2932.             ret
  2933.  
  2934. EndP        clrgwin
  2935.  
  2936. ;****************** outstr() -- Output string
  2937. ;void outstr(int x, int y, char *str);
  2938.  
  2939. Proc        outstr
  2940.  
  2941.             push  bp                ; pascal stack frame
  2942.             mov   bp, sp
  2943.             push  es
  2944.             pusha
  2945.  
  2946.             push  bp                ; get 8-line font
  2947.             mov   ax, 1130h
  2948.             mov   bh, 3
  2949.             int   10h
  2950.             mov   di, bp
  2951.             pop   bp
  2952.  
  2953.             mov   si, [bp+4]        ; get parameters
  2954.             mov   cx, [bp+8]
  2955.             mov   dx, [bp+6]
  2956.  
  2957. d_1:        lodsb                   ; get char (al)
  2958.             test  al, al
  2959.             jz    d_5
  2960.             mov   bl, al            ; get offset (bx)
  2961.             xor   bh, bh
  2962.             shl   bx, 3
  2963.  
  2964. d_2:        mov   al, [es:bx+di]    ; get font byte
  2965.             mov   ah, 8
  2966.  
  2967. d_3:        add   al, al            ; check the bit
  2968.             jnc   d_4
  2969.             push  cx dx             ; set the pixel
  2970.             call  putpix
  2971. d_4:        inc   cx                ; next pixel
  2972.             dec   ah                ; loop
  2973.             jnz   d_3
  2974.  
  2975.             sub   cx, 8             ; fix the position
  2976.             inc   dx                ; next line
  2977.             inc   bx                ; loop
  2978.             test  bx, 7
  2979.             jnz   d_2
  2980.  
  2981.             sub   dx, 8             ; fix the position
  2982.             add   cx, 8
  2983.             jmp   d_1               ; loop
  2984.  
  2985. d_5:        popa                    ; return code
  2986.             pop   es bp
  2987.             ret   6
  2988.  
  2989. EndP        outstr
  2990.  
  2991. ;****************** getimage() -- Save a rectangular image
  2992. ;void getimage(void *buf, int x1, int y1, int x2, int y2);
  2993.  
  2994. Proc        getimage
  2995.  
  2996.             push  bp                ; pascal stack frame
  2997.             mov   bp, sp
  2998.             pusha
  2999.  
  3000.             mov   si, [bp+12]       ; get coordinates
  3001.             mov   ax, [bp+10]
  3002.             mov   bx, [bp+8]
  3003.             mov   cx, [bp+6]
  3004.             mov   dx, [bp+4]
  3005.  
  3006.             cmp   ax, cx            ; left to right, etc.
  3007.             jng   $+3
  3008.             xchg  ax, cx
  3009.             cmp   bx, dx
  3010.             jng   $+4
  3011.             xchg  bx, dx
  3012.  
  3013.             sub   cx, ax            ; figure out distances
  3014.             inc   cx
  3015.             sub   dx, bx
  3016.             inc   dx
  3017.             mov   [si], cx          ; store the distances
  3018.             mov   [si+2], dx
  3019.             add   si, 4
  3020.             mov   di, ax
  3021.  
  3022. e_1:        push  di cx             ; save pixel data
  3023. e_2:        push  di bx             ; read the pixel
  3024.             call  getpix
  3025.             mov   [si], al          ; store the value
  3026.             inc   si
  3027.             inc   di                ; next pixel
  3028.             loop  e_2               ; loop
  3029.  
  3030.             pop   cx di             ; restore data
  3031.             inc   bx                ; next line
  3032.             dec   dx                ; loop
  3033.             jnz   e_1
  3034.  
  3035.             popa                    ; return code
  3036.             pop   bp
  3037.             ret   10
  3038.  
  3039. EndP        getimage
  3040.  
  3041. ;****************** putimage() -- Restore a rectangular image
  3042. ;void putimage(void *buf, int x1, int y1);
  3043.  
  3044. Proc        putimage
  3045.  
  3046.             push  bp                ; pascal stack frame
  3047.             mov   bp, sp
  3048.             pusha
  3049.             call  getgcolor         ; save old color
  3050.             push  ax
  3051.  
  3052.             mov   si, [bp+8]        ; get coordinates
  3053.             mov   di, [bp+6]
  3054.             mov   bx, [bp+4]
  3055.  
  3056.             lodsw                   ; load the distances
  3057.             mov   cx, ax
  3058.             lodsw
  3059.             mov   dx, ax
  3060.  
  3061. f_1:        push  di cx             ; save pixel data
  3062. f_2:        lodsb                   ; load a byte
  3063.             push  ax                ; set the color
  3064.             call  setgcolor
  3065.             push  di bx             ; write the pixel
  3066.             call  putpix
  3067.             inc   di                ; next pixel
  3068.             loop  f_2               ; loop
  3069.  
  3070.             pop   cx di             ; restore data
  3071.             inc   bx                ; next line
  3072.             dec   dx                ; loop
  3073.             jnz   f_1
  3074.  
  3075.             call  setgcolor         ; restore old color
  3076.             popa                    ; return code
  3077.             pop   bp
  3078.             ret   6
  3079.  
  3080. EndP        putimage
  3081.  
  3082. End
  3083.  
  3084. ~~~C_GRAPH3
  3085. Ideal
  3086. Jumps
  3087.  
  3088. Extrn       putpix:near, putrow:near, GMode:byte
  3089. Public      circle, ellipse
  3090. Public      fcircle, fellipse
  3091.  
  3092. Model Tiny
  3093. P186
  3094. CodeSeg
  3095.  
  3096. ;**************************** circle() -- Draw a circle
  3097. ;void circle(int x, int y, int r);
  3098.  
  3099. Proc        circle
  3100.  
  3101.             push  bp                ; pascal stack frame
  3102.             mov   bp, sp
  3103.             pusha
  3104.  
  3105.             mov   ax, [bp+4]        ; height
  3106.  
  3107.             cmp   [GMode], 1        ; check graphics mode
  3108.             je    c_1
  3109.             test  [GMode], 2
  3110.             jz    $+4
  3111.             shr   ax, 1
  3112.  
  3113.             mov   bx, 6             ; fix 6/5 aspect
  3114.             imul  bx
  3115.             dec   bx
  3116.             idiv  bx
  3117.  
  3118. c_1:        push  [bp+8] [bp+6]     ; ellipse with same radii
  3119.             push  ax [bp+4]
  3120.             call  ellipse
  3121.  
  3122.             popa                    ; return code
  3123.             pop   bp
  3124.             ret   6
  3125.  
  3126. EndP        circle
  3127.  
  3128. ;**************************** ellipse() -- Draw an ellipse
  3129. ;void ellipse(int x, int y, int xr, int yr);
  3130.  
  3131. Proc        ellipse
  3132.  
  3133.             push  bp                ; pascal stack frame
  3134.             mov   bp, sp
  3135.             pusha
  3136.  
  3137.             cmp   [word bp+6], 0    ; can't do radius 0
  3138.             jle   a_4
  3139.             cmp   [word bp+4], 0
  3140.             jle   a_4
  3141.  
  3142.             mov   ax, [bp+6]        ; jump to x or y loop
  3143.             cmp   ax, [bp+4]
  3144.             jl    a_2
  3145.  
  3146.             xor   si, si            ; x-major loop
  3147.             mov   di, [bp+6]
  3148.             shl   di, 5
  3149.  
  3150. a_1:        mov   ax, di            ; figure out y-position
  3151.             imul  [word bp+4]
  3152.             idiv  [word bp+6]
  3153.             mov   bx, ax
  3154.             add   bx, 16
  3155.             sar   bx, 5
  3156.             add   bx, [bp+8]
  3157.  
  3158.             mov   cx, si            ; set up for first pixel
  3159.             add   cx, 16
  3160.             sar   cx, 5
  3161.             push  cx
  3162.             add   cx, [bp+10]
  3163.  
  3164.             push  cx bx             ; draw first pixel
  3165.             call  putpix
  3166.  
  3167.             pop   cx                ; set up for second pixel
  3168.             neg   cx
  3169.             add   cx, [bp+10]
  3170.  
  3171.             push  cx bx             ; draw second pixel
  3172.             call  putpix
  3173.  
  3174.             mov   ax, di            ; linear shear algorithm
  3175.             cwd                     ; move by one pixel-width
  3176.             idiv  [word bp+6]
  3177.             add   si, ax
  3178.             mov   ax, si
  3179.             cwd
  3180.             idiv  [word bp+6]
  3181.             sub   di, ax
  3182.  
  3183.             test  ax, ax            ; loop
  3184.             jnl   a_1
  3185.             jmp   a_4
  3186.  
  3187. a_2:        xor   si, si            ; y-major loop
  3188.             mov   di, [bp+4]
  3189.             shl   di, 5
  3190.  
  3191. a_3:        mov   bx, di            ; figure out y-position
  3192.             add   bx, 16
  3193.             sar   bx, 5
  3194.             add   bx, [bp+8]
  3195.  
  3196.             mov   ax, si            ; set up for first pixel
  3197.             imul  [word bp+6]
  3198.             idiv  [word bp+4]
  3199.             mov   cx, ax
  3200.             add   cx, 16
  3201.             sar   cx, 5
  3202.             push  cx
  3203.             add   cx, [bp+10]
  3204.  
  3205.             push  cx bx             ; draw first pixel
  3206.             call  putpix
  3207.  
  3208.             pop   cx                ; set up for second pixel
  3209.             neg   cx
  3210.             add   cx, [bp+10]
  3211.  
  3212.             push  cx bx             ; draw second pixel
  3213.             call  putpix
  3214.  
  3215.             mov   ax, di            ; linear shear algorithm
  3216.             cwd                     ; move by one pixel-width
  3217.             idiv  [word bp+4]
  3218.             add   si, ax
  3219.             mov   ax, si
  3220.             cwd
  3221.             idiv  [word bp+4]
  3222.             sub   di, ax
  3223.  
  3224.             test  ax, ax            ; loop
  3225.             jnl   a_3
  3226.  
  3227. a_4:        popa                    ; return code
  3228.             pop   bp
  3229.             ret   8
  3230.  
  3231. EndP        ellipse
  3232.  
  3233. ;**************************** fcircle() -- Draw a filled circle
  3234. ;void fcircle(int x, int y, int r);
  3235.  
  3236. Proc        fcircle
  3237.  
  3238.             push  bp                ; pascal stack frame
  3239.             mov   bp, sp
  3240.             pusha
  3241.  
  3242.             mov   ax, [bp+4]        ; height
  3243.  
  3244.             cmp   [GMode], 1        ; check graphics mode
  3245.             je    d_1
  3246.             test  [GMode], 2
  3247.             jz    $+4
  3248.             shr   ax, 1
  3249.  
  3250.             mov   bx, 6             ; fix 6/5 aspect
  3251.             imul  bx
  3252.             dec   bx
  3253.             idiv  bx
  3254.  
  3255. d_1:        push  [bp+8] [bp+6]     ; ellipse with same radii
  3256.             push  ax [bp+4]
  3257.             call  fellipse
  3258.  
  3259.             popa                    ; return code
  3260.             pop   bp
  3261.             ret   6
  3262.  
  3263. EndP        fcircle
  3264.  
  3265. ;**************************** fellipse() -- Draw a filled ellipse
  3266. ;void fellipse(int x, int y, int xr, int yr);
  3267.  
  3268. Proc        fellipse
  3269.  
  3270.             push  bp                ; pascal stack frame
  3271.             mov   bp, sp
  3272.             pusha
  3273.  
  3274.             cmp   [word bp+6], 0    ; can't do radius 0
  3275.             jle   b_4
  3276.             cmp   [word bp+4], 0
  3277.             jle   b_4
  3278.  
  3279.             mov   ax, [bp+6]        ; jump to x or y loop
  3280.             cmp   ax, [bp+4]
  3281.             jl    b_2
  3282.  
  3283.             xor   si, si            ; x-major loop
  3284.             mov   di, [bp+6]
  3285.             shl   di, 5
  3286.  
  3287. b_1:        mov   ax, di            ; figure out y-position
  3288.             imul  [word bp+4]
  3289.             idiv  [word bp+6]
  3290.             mov   bx, ax
  3291.             add   bx, 16
  3292.             sar   bx, 5
  3293.             add   bx, [bp+8]
  3294.  
  3295.             mov   cx, si            ; set up left end of line
  3296.             add   cx, 16
  3297.             sar   cx, 5
  3298.             mov   ax, [bp+10]
  3299.             add   cx, ax
  3300.             push  cx
  3301.             neg   cx                ; set up right end of line
  3302.             add   cx, ax
  3303.             add   cx, ax
  3304.             push  cx bx             ; draw line
  3305.             call  putrow
  3306.  
  3307.             mov   ax, di            ; linear shear algorithm
  3308.             cwd                     ; move by one pixel-width
  3309.             idiv  [word bp+6]
  3310.             add   si, ax
  3311.             mov   ax, si
  3312.             cwd
  3313.             idiv  [word bp+6]
  3314.             sub   di, ax
  3315.  
  3316.             test  ax, ax            ; loop
  3317.             jnl   b_1
  3318.             jmp   b_4
  3319.  
  3320. b_2:        xor   si, si            ; y-major loop
  3321.             mov   di, [bp+4]
  3322.             shl   di, 5
  3323.  
  3324. b_3:        mov   bx, di            ; figure out y-position
  3325.             add   bx, 16
  3326.             sar   bx, 5
  3327.             add   bx, [bp+8]
  3328.  
  3329.             mov   ax, si            ; set up left end of line
  3330.             imul  [word bp+6]
  3331.             idiv  [word bp+4]
  3332.             mov   cx, ax
  3333.             add   cx, 16
  3334.             sar   cx, 5
  3335.             mov   ax, [bp+10]
  3336.             add   cx, ax
  3337.             push  cx
  3338.             neg   cx                ; set up right end of line
  3339.             add   cx, ax
  3340.             add   cx, ax
  3341.             push  cx bx             ; draw line
  3342.             call  putrow
  3343.  
  3344.             mov   ax, di            ; linear shear algorithm
  3345.             cwd                     ; move by one pixel-width
  3346.             idiv  [word bp+4]
  3347.             add   si, ax
  3348.             mov   ax, si
  3349.             cwd
  3350.             idiv  [word bp+4]
  3351.             sub   di, ax
  3352.  
  3353.             test  ax, ax            ; loop
  3354.             jnl   b_3
  3355.  
  3356. b_4:        popa                    ; return code
  3357.             pop   bp
  3358.             ret   8
  3359.  
  3360. EndP        fellipse
  3361.  
  3362. End
  3363.  
  3364. ~~~C_GRAPH4
  3365. Ideal
  3366. Jumps
  3367.  
  3368. Extrn       allocmem:near, freemem:near, putrow:near
  3369. Public      triangle
  3370.  
  3371. Model Tiny
  3372. P186
  3373. CodeSeg
  3374.  
  3375. ;****************** triangle() -- Draw a filled triangle
  3376. ;void triangle(int x1, int y1, int x2, int y2, int x3, int y3);
  3377.  
  3378. Proc        triangle
  3379.  
  3380.             push  bp                ; pascal stack frame
  3381.             mov   bp, sp
  3382.             push  es
  3383.             pusha
  3384.  
  3385.             push  ds                ; same segment
  3386.             pop   es
  3387.  
  3388.             push  1920              ; allocate buffer
  3389.             call  allocmem
  3390.             test  ax, ax
  3391.             je    a_4
  3392.             mov   [a_buf], ax       ; save buffer
  3393.  
  3394.             mov   cx, 480           ; set up for loop
  3395.             xchg  di, ax
  3396.             mov   ax, 7FFFh
  3397.  
  3398. a_1:        stosw                   ; write left
  3399.             inc   ax
  3400.             stosw                   ; write right
  3401.             dec   ax
  3402.             loop  a_1
  3403.  
  3404.             push  [bp+14] [bp+12]   ; scan line 1
  3405.             push  [bp+10] [bp+8]
  3406.             call  a_5
  3407.  
  3408.             push  [bp+14] [bp+12]   ; scan line 2
  3409.             push  [bp+6] [bp+4]
  3410.             call  a_5
  3411.  
  3412.             push  [bp+10] [bp+8]    ; scan line 3
  3413.             push  [bp+6] [bp+4]
  3414.             call  a_5
  3415.  
  3416.             mov   cx, 480           ; set up for loop
  3417.             mov   si, [a_buf]
  3418.             xor   dx, dx
  3419.  
  3420. a_2:        lodsw                   ; read line
  3421.             xchg  bx, ax
  3422.             lodsw
  3423.             cmp   bx, ax            ; test line
  3424.             jg    a_3
  3425.             push  bx ax dx          ; if ok, draw line
  3426.             call  putrow
  3427. a_3:        inc   dx                ; move down
  3428.             loop  a_2
  3429.  
  3430.             push  [a_buf]           ; free buffer
  3431.             call  freemem
  3432.  
  3433. a_4:        popa                    ; return code
  3434.             pop   es
  3435.             pop   bp
  3436.             ret   12
  3437.  
  3438. a_5:        enter 4, 0              ; pascal stack frame
  3439.             pusha                   ; with local vars
  3440.  
  3441.             mov   ax, [bp+10]       ; get coordinates
  3442.             mov   bx, [bp+8]
  3443.             mov   cx, [bp+6]
  3444.             mov   dx, [bp+4]
  3445.  
  3446.             mov   si, cx            ; get x, y distance
  3447.             sub   si, ax
  3448.             jge   $+4
  3449.             neg   si
  3450.             mov   di, dx
  3451.             sub   di, bx
  3452.             jge   $+4
  3453.             neg   di
  3454.  
  3455.             mov   [bp-2], si        ; jump to x or y loop
  3456.             mov   [bp-4], di
  3457.             cmp   si, di
  3458.             jle   a_9
  3459.  
  3460.             cmp   ax, cx            ; go in the x direction
  3461.             jle   a_6
  3462.             xchg  ax, cx
  3463.             xchg  bx, dx
  3464.  
  3465. a_6:        xchg  ax, dx            ; get distance (cx)
  3466.             sub   cx, dx
  3467.             inc   cx
  3468.             sub   ax, bx            ; get y increment (ax)
  3469.             sar   ax, 16
  3470.             add   ax, ax
  3471.             inc   ax
  3472.             shr   si, 1             ; setup error term (si)
  3473.             sub   di, si
  3474.             mov   si, di
  3475.  
  3476. a_7:        call  a_14              ; scan point
  3477.             test  si, si            ; check for y move
  3478.             jl    a_8
  3479.  
  3480.             add   bx, ax            ; move in y direction
  3481.             sub   si, [bp-2]
  3482.  
  3483. a_8:        inc   dx                ; move in x direction
  3484.             add   si, [bp-4]
  3485.             loop  a_7               ; loop
  3486.             jmp   a_13
  3487.  
  3488. a_9:        cmp   bx, dx            ; go in the y direction
  3489.             jle   a_10
  3490.             xchg  ax, cx
  3491.             xchg  bx, dx
  3492.  
  3493. a_10:       xchg  ax, cx            ; get distance (cx)
  3494.             sub   dx, bx
  3495.             xchg  cx, dx
  3496.             inc   cx
  3497.             sub   ax, dx            ; get x increment (ax)
  3498.             sar   ax, 16
  3499.             add   ax, ax
  3500.             inc   ax
  3501.             shr   di, 1             ; setup error term (si)
  3502.             sub   si, di
  3503.  
  3504. a_11:       call  a_14              ; scan point
  3505.             test  si, si            ; check for x move
  3506.             jl    a_12
  3507.  
  3508.             add   dx, ax            ; move in x direction
  3509.             sub   si, [bp-4]
  3510.  
  3511. a_12:       inc   bx                ; move in y direction
  3512.             add   si, [bp-2]
  3513.             loop  a_11              ; loop
  3514.  
  3515. a_13:       popa                    ; return code
  3516.             pop   es
  3517.             leave
  3518.             ret   8
  3519.  
  3520. a_14:       pusha                   ; save regs
  3521.  
  3522.             cmp   bx, 480           ; check range
  3523.             jae   a_16
  3524.  
  3525.             mov   si, [a_buf]       ; pointer to line
  3526.             shl   bx, 2
  3527.             add   si, bx
  3528.  
  3529.             cmp   dx, [si]          ; update left side
  3530.             jg    a_15
  3531.             mov   [si], dx
  3532.  
  3533. a_15:       cmp   dx, [si+2]        ; update right side
  3534.             jl    a_16
  3535.             mov   [si+2], dx
  3536.  
  3537. a_16:       popa                    ; return code
  3538.             ret
  3539.  
  3540. a_buf       dw    0                 ; buffer
  3541.  
  3542. EndP        triangle
  3543.  
  3544. End
  3545.